【发布时间】:2021-09-14 21:38:07
【问题描述】:
我一直在用 goroutine 做一些测试,我注意到使用这段代码的一个奇怪的行为(对我来说):
游乐场:https://play.golang.org/p/Py4oqGqkYKm
package main
import (
"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
看起来第二个 goroutines 是首先被调用的(比如 LIFO)。考虑到这一点,我尝试反转 goroutines,并收到了我所期望的答案:
游乐场:https://play.golang.org/p/BC1r3NK6RBm
package main
import (
"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 版本:
go version go1.16.2 linux/amd64
【问题讨论】:
-
@PenelopeStevens 这个评论有助于更好地理解......我们无法控制首先调用哪个互斥锁,对吧?所以,参加我想做的事情,我需要使用这样的频道:play.golang.org/p/OVK4hTQSu_d 对吗?
-
“并发进程”的全部意义在于它们的相对顺序没有定义。