为了账号安全,请及时绑定邮箱和手机立即绑定

为什么最后一个戈鲁廷首先在循环中以两个戈鲁廷开始?

为什么最后一个戈鲁廷首先在循环中以两个戈鲁廷开始?

Go
慕姐4208626 2022-09-12 16:42:33
我一直在用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()。

该程序确保的唯一排序是通过等待组:每对戈鲁丁将在下一对开始之前完成。


查看完整回答
反对 回复 2022-09-12
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

Go 例程提供并发性,并在具有独立堆栈内存的共享堆分配之上工作。它们的目的是在多核系统之上提供并发执行。它们如何并行执行没有任何支配因素。这由实际的处理器决定。我们只通过抽象层使用处理器。

实际上,没有并发系统可以管理/预测结果。


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 68 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信