2017-10-17 193 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的符號周圍。