无法使用书中的例子模拟死锁。

问题描述 投票:0回答:1

我正在阅读Katherine Cox-Buday所著的《Go的并发性。开发者的工具和技术",作者是Katherine Cox-Buday。 我被一个非常简单的例子卡住了,这个例子是为了模拟死锁。这个片段看起来是这样的。

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 concurrency mutex
1个回答
1
投票

你的实现是错误的。死锁是由循环锁定触发的,只有当你以不同的顺序锁定两个锁时才会发生。所以,可以这样做。

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

当锁的顺序和上面一样时,第一个锁 printSum 会锁定 a 和第二个将锁定 b然后他们就会等着另一把锁松开,而这是不会发生的。

© www.soinside.com 2019 - 2024. All rights reserved.