golang

时间:2017-10-17 09:29:12

标签: go locking

src/sync/rwmutex.go文件中,我们可以看到" Lock"的定义如下:

func (rw *RWMutex) Lock() {
    if race.Enabled {
        _ = rw.w.state
        race.Disable()
    }
    // First, resolve competition with other writers.
    rw.w.Lock()
    // Announce to readers there is a pending writer.
    r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
    // Wait for active readers.
    if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
        runtime_Semacquire(&rw.writerSem)
    }
    if race.Enabled {
        race.Enable()
        race.Acquire(unsafe.Pointer(&rw.readerSem))
        race.Acquire(unsafe.Pointer(&rw.writerSem))
    }
}

所以我真的很想知道

atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders

这句话的意思。正如它所说,如何向读者宣布?如何理解?

2 个答案:

答案 0 :(得分:0)

你喜欢魔法吗?这就是; o)不......我只是在开玩笑。

我们可以从

开始
atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)

这个来自rw.readerCount的原子减去rwmutexMaxReaders。新值存储在rw.readerCount中,也由函数返回。当您添加rwmutexMaxReaders时,您只需在AddInt32之前计算旧值rw.readerCount。

答案 1 :(得分:0)

在RWMutex上,一个调用Lock的编写器阻止更多读者获取RLock。这样做是为了防止starvation作者。

假设以下情形:

  1. 假设读者已获得读锁定,则rw.readerCount将为1.

  2. 然后,编写器尝试获取写锁定。在获得写锁定(line 93)之后,它现在必须向所有读者发出信号,表示作者正在等待(因此他们无法继续)并等待所有读者完成。通过将rw.readerCount设置为负值({​​{1}})来设置信号。 atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)的值现在为rw.readerCount。请注意1-rwmutexMaxReaders不是0,因此作者知道有一个读者仍在阅读。

  3. 新的Reader现在想要获取读锁定,它会向r添加1(第48行)并检查它是否为负数。如果它是否定的,作者已将其设置为这样,我们应该等待作者完成然后再继续。

  4. 信号发生在rw.readerCount的标志周围。