不明显的僵局情况

时间:2018-05-25 07:52:59

标签: go synchronization

你能解释为什么会发生这种僵局吗?

package main

import (
    "sync"
    "fmt"
    "runtime"
)

func main() {
    m := sync.RWMutex{}
    go func(){
        m.RLock()
        runtime.Gosched()
        m.RLock()
        m.RUnlock()
        m.RUnlock()
    }()

    runtime.Gosched()
    m.Lock()
    m.Unlock()

    fmt.Println("works")
}

为什么这个死锁总是主要发生在我身上。 这可能是调度程序的怪癖吗?

1 个答案:

答案 0 :(得分:1)

来自RWMutex doc:

  

如果goroutine持有RWMutex用于阅读而另一个goroutine可能   调用Lock,没有goroutine应该能够获得读取   锁定,直到释放初始读锁定。特别是这个   禁止递归读锁定。这是为了确保锁定   最终变得可用;阻止的锁定呼叫会排除新读者   获得锁定。

当发生死锁时,代码中发生了什么:

  1. 第一个RLock()
  2. Lock()//此调用等待直到第一个Rlock()发布并阻止对未来Rlocks的调用()
  3. Rlock()//此调用等待直到Lock()被释放