1 回答
TA贡献1836条经验 获得超5个赞
您的代码中没有任何恶意内容,因此这就是竞争检测器未检测到任何内容的原因。您的counter
变量始终atomic
通过启动的 goroutine 中的包进行访问,而不是直接访问。
有时你得到 1000 个有时更少的原因是由于运行 goroutine 的活动线程的数量:GOMAXPROCS
。在 Go Playground 上它是 1,所以任何时候你都有一个活动的 goroutine(所以基本上你的应用程序是按顺序执行的,没有任何并行性)。并且当前的 goroutine 调度器不会任意将 goroutine 停放。
在你的本地机器上,你可能有一个多核 CPU,并且GOMAXPROCS
默认为可用逻辑 CPU 的数量,因此GOMAXPROCS
大于 1,因此你有多个并行运行的 goroutine (真正的并行,而不仅仅是并发)。
看这个片段:
v := atomic.LoadInt64(&counter)
v++
atomic.StoreInt64(&counter, v)
您加载counter值并将其分配给v,您递增v,然后存储回递增的值v。如果 2 个并行 goroutine 同时执行此操作会发生什么?假设两者都加载 value 100。两者都会增加其本地副本:101. 两者都回写101,尽管应该是在102。
是的,原子递增计数器的正确方法是atomic.AddInt64()
这样使用:
for i := 0; i < num; i++ {
go func() {
atomic.AddInt64(&counter, 1)
wg.Done()
}()
}
这样无论是什么,你总是会得到 1000 GOMAXPROCS。
- 1 回答
- 0 关注
- 100 浏览
添加回答
举报