我一直在用goroutines做一些测试,我注意到一个奇怪的行为(对我来说)使用这个代码:游乐场: https://play.golang.org/p/Py4oqGqkYKmpackage mainimport ( "fmt" "sync")var ( mu sync.Mutex wg sync.WaitGroup)func main() { var x int for i := 0; i < 10; i++ { wg.Add(2) go func() { mu.Lock() x = i mu.Unlock() wg.Done() }() go func() { mu.Lock() fmt.Print("x: ", x, " \n") mu.Unlock() wg.Done() }() wg.Wait() }}我期望输出如下:x: 0 x: 1 x: 2 x: 3 x: 4 x: 5 x: 6 x: 7 x: 8 x: 9 但我收到了:x: 0 x: 0 x: 1 x: 2 x: 3 x: 4 x: 5 x: 6 x: 7 x: 8 看起来第二个戈鲁廷被称为第一个(如后进先出)。想到这一点,我试图反转戈鲁廷,我得到了我所期望的答案:游乐场: https://play.golang.org/p/BC1r3NK6RBmpackage mainimport ( "fmt" "sync")var ( mu sync.Mutex wg sync.WaitGroup)func main() { var x int for i := 0; i < 10; i++ { wg.Add(2) go func() { mu.Lock() fmt.Print("x: ", x, " \n") mu.Unlock() wg.Done() }() go func() { mu.Lock() x = i mu.Unlock() wg.Done() }() wg.Wait() }}输出:x: 0 x: 1 x: 2 x: 3 x: 4 x: 5 x: 6 x: 7 x: 8 x: 9 任何人都可以帮助我理解这种行为吗?转到版本:go version go1.16.2 linux/amd64
2 回答
SMILET
TA贡献1796条经验 获得超4个赞
Go 语言不指定 goroutine 在显式同步之外使用通道、互斥锁、等待组等执行的顺序。该规范允许两个程序的两个输出。
您正在观察互斥体的获取顺序,而不是戈鲁丁开始的顺序。可能是大肠按预期的顺序开始,但意外的大肠首先调用 Lock()。
该程序确保的唯一排序是通过等待组:每对戈鲁丁将在下一对开始之前完成。
一只名叫tom的猫
TA贡献1906条经验 获得超3个赞
Go 例程提供并发性,并在具有独立堆栈内存的共享堆分配之上工作。它们的目的是在多核系统之上提供并发执行。它们如何并行执行没有任何支配因素。这由实际的处理器决定。我们只通过抽象层使用处理器。
实际上,没有并发系统可以管理/预测结果。
- 2 回答
- 0 关注
- 68 浏览
添加回答
举报
0/150
提交
取消