sync.mutex 锁不起作用的困惑
在学习 go 时,遇到 sync.mutex 无法正常工作的困扰,代码如下:
package main import ( "fmt" "sync" "time" ) func main() { haslockandwait() } func haslockandwait() { var a = 0 var wg sync.waitgroup // 问题出现在这里,将 locker 声明移到 for 循环内 for i := 0; i < 1000; i++ { wg.add(1) go func() { defer wg.done() var locker sync.mutex locker.lock() defer locker.unlock() a++ fmt.println("a 的值为:", a) }() } wg.wait() fmt.println("a 的最终值为:", a) }
登录后复制
我们期望最终的 a 值为 1000,但实际得到的是随机值,这是因为将 locker 声明在 for 循环内部导致了每个协程都有了自己的 locker 对象,无法实现互斥锁的目的。
解决方法有两种:
- 将 locker 移到 for 循环外:
var locker sync.mutex for i := 0; i < 1000; i++ { wg.add(1) go func() { defer wg.done() locker.lock() defer locker.unlock() a++ fmt.println("a 的值为:", a) }() }
登录后复制
通过将 locker 移到循环外,确保所有协程共享同一把锁,从而实现并发控制。
- 使用 atomic 包:
atomic.addint64() 可用于原子地对 int64 变量进行增量操作,确保并发安全:
import "sync/atomic" var a int64 for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() atomic.AddInt64(&a, 1) fmt.Println("a 的值为:", atomic.LoadInt64(&a)) }() }
登录后复制
以上就是为什么我的 sync.Mutex 锁不起作用?的详细内容,更多请关注抖狐科技其它相关文章!
-
文明6地图钉mod怎么用 文明6地图钉mod使用方法
文明6地图钉全搜集攻略,成就全解锁必看!在《文明6》游戏中,地图钉是不可错过的搜集要素,全搜集更能达成成就解锁的喜悦。然而,地图钉的搜集难度不低,需要玩家耐心探索和搜寻。php小编苹果特此带来《文明6...
-
《怪物猎人 荒野》特别情报节目将于10月23日播出
capcom预告,为大家带来《怪物猎人 荒野》最新消息的特别节目“monster hunter showcase”将于10月23日晚上10点播出! 节目中,《怪物猎人 荒野》的制作人辻本良三将会为大...
-
python3.9.2下载教程
python 3.9.2 下载步骤:访问官网下载页面:https://www.python.org/downloads/选择操作系统,下载对应安装程序安装 python,按照提示完成操作Python...
-
骁龙8gen4价位
骁龙8 gen 4官方定价为1,050美元。其价格受制造成本、研发费用、市场竞争和品牌溢价影响。设备厂商定价还取决于设备规格、市场定位和品牌形象。骁龙8 Gen 4的价位 骁龙8 Gen 4的官方定价...
-
Java函数与方法在扩展性和可复用性方面的不同
Java 函数与方法的扩展性和可复用性 简介 在 Java 中,函数和方法是用以组织和封装代码块的基本结构。尽管它们有着相似的目的,但在扩展性和可复用性方面却有着关键的区别。 函数 立即学习“Java...