2017-10-17 200 views
1

src/sync/rwmutex.go文件中的implementions,我们可以看到的 “锁定” 的定义如下:RWMutex.Lock()在golang

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 

这句话手段。正如它所说,如何向读者公布?如何理解它?

+1

rw.readerCount <= rwmutexMaxReaders,因此rw.readerCount-rwmutexMaxReaders使readerCount 0或negativ(信号)。加回rwmutxMaxReaders使r等于readerWait的实数。 – Volker

回答

0

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

我们可以用

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

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

0

在RWMutex上,调用Lock的作者可以防止更多读者获取RLock。这是为了防止作者的starvation

假设以下情形:

  1. 假设读者已经获得了读取锁,然后rw.readerCount将1

  2. 作家则试图获取写锁。在获得写入锁定(line 93)之后,它现在必须向所有读者发出信号,表明作者正在等待(所以他们不能继续)并等待所有读取器完成。该信号通过将rw.readerCount设置为负值(atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders))来设置。 rw.readerCount的值现在为1-rwmutexMaxReaders。请注意,r不是0,所以作者知道有一位读者仍在阅读。

  3. 新读者现在想要获取读锁,它将012加入rw.readerCount(第48行),并检查它是否为负数。如果作者认为这是负面的,那么我们应该等待作家完成后再继续。

信号发生在rw.readerCount的符号周围。