1

Is calling the Wait() method of sync.Cond safe when according to the documentation, it performs an Unlock() first?

Assume we are checking for a condition to be met:

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

And:

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
}

Since Wait() performs an Unlock, should (A) has a locking of it's own? Or being atomic?

4

1 回答 1

2

是的,Wait即使它L.Unlock()第一次调用也是安全的,但在调用之前和检查条件之前获取锁是必不可少的,Wait因为在这种情况下,两者都不是线程安全的。

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

  1. 调用的 goroutineWait获得了锁,检查了条件,发现它不令人满意。
  2. 现在它等待,但为了允许更改条件,它需要返回锁。Wait自动为您执行此操作,然后暂停 goroutine。
  3. 现在条件可能发生变化,最终 goroutine 被Broadcastor唤醒Signal。然后它获取锁以再次检查条件(这必须为每个等待的 goroutine 一个接一个地发生,否则将无法知道现在有多少 goroutine 正在自由运行)。
于 2015-11-27T12:31:14.470 回答