【发布时间】:2020-02-21 14:13:59
【问题描述】:
正如此链接https://golang.org/ref/mem 中所述,以下代码使用了不正确的同步:
var a, b int
func f() {
a = 1
b = 2
}
func g() {
print(b)
print(a)
}
func main() {
go f()
g()
}
因为它可能会打印 a = 0 和 b = 2。
但是,我想知道在下面的代码中是否可能出现这种结果,其中 a 和 b 被 Lock 保护:
var a, b int
var mu sync.Mutex
func f() {
mu.Lock()
a = 1
b = 2
mu.Unlock()
}
func g() {
mu.Lock()
print(b)
print(a)
mu.Unlock()
}
func main() {
go f()
g()
}
因为链接说:
For any sync.Mutex or sync.RWMutex variable l and n < m, call n of l.Unlock() happens before call m of l.Lock() returns.
但是不清楚a和b的赋值是否保证在Unlock语句之前执行
【问题讨论】:
-
第一个锁是解锁操作,是系统调用。您正在锁定打印操作。当线程进入系统调用(等待操作)时,它创建条件将上下文切换到之前创建的goroutine。它遇到第二个锁并等待直到第一个锁被解锁。因此,变量只有在打印后才会更改。
-
@LaevusDexter:这是不正确的,因为
g调用了系统调用,所以没有隐含的同步。无法保证调度程序会在f获得锁定并更改值之前返回到main。
标签: go concurrency mutex memory-model