Go 无法使用书本中的示例模拟死锁

Go 无法使用书本中的示例模拟死锁,go,concurrency,mutex,Go,Concurrency,Mutex,我正在阅读Katherine Cox Buday的“Go中的并发:开发人员的工具和技术”,我被困在一个非常简单的示例中,该示例旨在模拟死锁。代码片段如下所示 func main() { var wg sync.WaitGroup printSum := func(a, b *somevar) { defer wg.Done() a.mu.Lock() defer a.mu.Unlock() time.Sleep(1

我正在阅读Katherine Cox Buday的“Go中的并发:开发人员的工具和技术”,我被困在一个非常简单的示例中,该示例旨在模拟死锁。代码片段如下所示

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()
}

然而,当我尝试运行这个时,我总是得到输出

sum is - 352 
sum is - 354 
在本例中,printSum的第二个实例是否会等待var a上的锁并仅在获取锁时继续,还是会继续并获取var b上的锁?
这本书是2015年出版的,因此,语言行为是否发生了变化,从而使示例无效

您的实现是错误的。死锁是由循环锁触发的,只有在您以不同的顺序锁定这两个锁时才会发生。因此,请改为:

go printSum(&a, &b)
go printSum(&b, &a)

当锁的顺序如上所述时,第一个
printSum
将锁定
a
,第二个将锁定
b
,然后他们将等待另一个锁释放,这永远不会发生。

你说得对。我似乎误读了书中的例子。非常感谢。