无法使用书中的示例模拟死锁
Unable to simulate deadlock using example in book
我正在阅读 Katherine Cox-Buday 的 "Concurrency in Go: Tools and Techniques for Developers",并且被困在一个旨在模拟死锁的非常简单的示例中。该片段看起来像这样。
func main() {
var wg sync.WaitGroup
printSum := func(a, b *somevar) {
defer wg.Done()
a.mu.Lock()
defer a.mu.Unlock()
time.Sleep(1 * time.Second)
b.mu.Lock()
defer b.mu.Unlock()
fmt.Printf("sum is - %d \n", a.val + b.val)
}
var a, b somevar
a.val = 50
b.val = 300
wg.Add(2)
go printSum(&a, &b)
go printSum(&a, &b)
wg.Wait()
}
Figure describing how the deadlock occurs, as per the book
但是,当我尝试 运行 时,我总是得到输出。
sum is - 352
sum is - 354
在此示例中,printSum 的第二个实例是等待 var a 上的锁并仅在获取锁时继续,还是继续前进并获取 var b 上的锁?
这本书是 2015 年的,那么使示例无效的语言行为是否发生了变化?
你的实现是错误的。死锁是由循环锁触发的,只有当你以不同的顺序锁定两个锁时才会发生这种情况。所以,改为这样做:
go printSum(&a, &b)
go printSum(&b, &a)
当锁顺序如上,第一个printSum
会锁a
,第二个会锁b
,然后他们会等待另一个锁释放,这永远不会发生。
我正在阅读 Katherine Cox-Buday 的 "Concurrency in Go: Tools and Techniques for Developers",并且被困在一个旨在模拟死锁的非常简单的示例中。该片段看起来像这样。
func main() {
var wg sync.WaitGroup
printSum := func(a, b *somevar) {
defer wg.Done()
a.mu.Lock()
defer a.mu.Unlock()
time.Sleep(1 * time.Second)
b.mu.Lock()
defer b.mu.Unlock()
fmt.Printf("sum is - %d \n", a.val + b.val)
}
var a, b somevar
a.val = 50
b.val = 300
wg.Add(2)
go printSum(&a, &b)
go printSum(&a, &b)
wg.Wait()
}
Figure describing how the deadlock occurs, as per the book
但是,当我尝试 运行 时,我总是得到输出。
sum is - 352
sum is - 354
在此示例中,printSum 的第二个实例是等待 var a 上的锁并仅在获取锁时继续,还是继续前进并获取 var b 上的锁? 这本书是 2015 年的,那么使示例无效的语言行为是否发生了变化?
你的实现是错误的。死锁是由循环锁触发的,只有当你以不同的顺序锁定两个锁时才会发生这种情况。所以,改为这样做:
go printSum(&a, &b)
go printSum(&b, &a)
当锁顺序如上,第一个printSum
会锁a
,第二个会锁b
,然后他们会等待另一个锁释放,这永远不会发生。