同时调用`sync.Cond`的`Wait()`方法,安全吗?

时间:2015-11-27 09:57:55

标签: multithreading go concurrency locking shared-state

根据文档,调用Wait() sync.Cond方法是否安全?它首先执行Unlock()

假设我们正在检查要满足的条件:

func sample() {
    cond = &sync.Cond{L: &sync.Mutex{}} // accessible by other parts of program

    go func() {
        cond.L.Lock()
        for !condition() {
            cond.Wait()
        }
        // do stuff ...
        cond.L.Unlock()
    }()

    go func() {
        cond.L.Lock()
        mutation()
        cond.L.Unlock()

        cond.Signal()
    }()
}

func condition() bool {
    // assuming someSharedState is a more complex state than just a bool
    return someSharedState
}

func mutation() {
    // assuming someSharedState is a more complex state than just a bool
    // (A) state mutation on someSharedState
}

由于Wait()执行Unlock,应该(A)锁定它自己吗?还是原子?

1 个答案:

答案 0 :(得分:2)

是的,即使首先调用Wait,也可以安全地致电L.Unlock(),但在调用Wait之前和检查您的情况之前获取锁定至关重要,因为在这种情况下,两者都不是线程安全的。

  

Wait原子地解锁c.L 并暂停执行调用goroutine。稍后恢复执行后,Wait会在返回之前锁定c.L

  1. 调用Wait的goroutine获得了锁,检查了条件并发现它不令人满意。
  2. 现在它等待,但为了允许更改条件,它需要锁定回来。 Wait会自动为您执行此操作,然后暂停goroutine。
  3. 现在可能会发生病情变化,最终会被BroadcastSignal唤醒。然后它再次获取锁定以检查条件(这必须逐个为每个等待的goroutine发生,否则将无法确定现在有多少goroutine自由流动)。