golang sync.RWLock似乎会造成死锁?

时间:2015-01-22 05:20:20

标签: go mutex

我一直在使用RWLock读取mysql数据库,但似乎间歇性地下面的代码在等待解锁时锁定程序?

// Returns string value from key in table specified, third parameter should be set to false if it shouldn't be case senstive.
func (self *DBStore) GetString(table string, key string, vargs...interface{}) (output string) {

    defer func() { fmt.Println("GETSTRING Freeing Mutex!") }()
    self.mutex.RLock()
    fmt.Println("GETSTRING Got Mutex!")
    defer self.mutex.RUnlock()

    self.Get(table, key, &output, vargs...)
    return

}

// Retreive a value at key in table specified.
func (self *DBStore) Get(table string, key string, output interface{}, vargs...interface{}) (found bool) {

    defer func() { fmt.Println("GET Freeing Mutex!") }()
    fmt.Println("Requesting Mutex")
    self.mutex.RLock()
    fmt.Println("GET Got Mutex!")
    defer self.mutex.RUnlock()

现在有了上述内容,我可以看到我真的不需要在这里执行RLock而且我可以简单地删除它,但我的印象是读锁不应该干扰另一个读锁。它似乎也是断断续续的,通常需要我在运行之前运行相同的东西几次。

计划的输出是:

Requesting Mutex
GET Got Mutex!
GET Freeing Mutex!
GETSTRING Got Mutex!
Requesting Mutex

然后它就永远地坐着,锁着。我在这里缺少什么?

任何信息都将不胜感激!

go go go.4.4 darwin / amd64

1 个答案:

答案 0 :(得分:1)

在考虑背靠背RLock的问题之后,这是有道理的。

我没有在这里登录的是Locks,现在清楚的是一个条件正在发生在一个Lock进入背对背RLocks之间。

基本上锁是排队的。

(Thread 1) GetString -> Request Read Lock
(Thread 1) GetString -> Got Read Lock
(Thread 2) Set -> Request Write Lock (Blocked, queued.)
(Thread 1) Get -> Request Read Lock (Blocked, queued.)

来自http://golang.org/src/sync/rwmutex.go?s=862:888#L19

34        if atomic.AddInt32(&rw.readerCount, 1) < 0 {
35            // A writer is pending, wait for it.
36            runtime_Semacquire(&rw.readerSem)
37        }
相关问题