【发布时间】:2017-12-30 19:34:53
【问题描述】:
每次 for 循环迭代时,我都会在 goroutine 中运行一个函数,并且我使用 sync.WaitGroup 来确保 goroutines 全部完成。但是,我在用计数器测试并发性时出现了奇怪的行为。在下面的示例中,我尝试使用 4 种不同的技术(w、x、y、z)来跟踪线程数,并得到 4 种不同的结果。我理解的唯一结果是x,因为它在 for 循环本身中递增。我在这里错过了什么?
package main
import "fmt"
import "sync"
var w = 0
func main() {
x := 0
y := 0
z := 0
var wg sync.WaitGroup
for i := 0; i < 10000; i++ {
wg.Add(1)
x++
go func() {
z++
test(&y)
wg.Done()
}()
}
wg.Wait()
fmt.Println(w, x, y, z) // 8947 10000 8831 8816
}
func test(y *int) {
w++
*y++
}
【问题讨论】:
-
等待组按预期工作。问题是 w、y 和 z 存在数据竞争。
-
@CeriseLimón 我需要使用互斥锁来增加吗?实现这一目标的最有效方法是什么?
-
使用互斥锁或sync/atomic。如果没有看到您正在解决的实际问题,就很难对有效的解决方案发表评论。
标签: go concurrency synchronization goroutine