Go 語言的鎖

Go 語言提供兩類鎖: 互斥鎖(Mutex)和讀寫鎖(RWMutex)。
其中讀寫鎖(RWMutex)是基于互斥鎖(Mutex)實現(xiàn)的,我們看讀寫鎖的定義(sync/rwmutex.go):

type RWMutex struct {
    w           Mutex  // held if there are pending writers
    writerSem   uint32 // semaphore for writers to wait for completing readers
    readerSem   uint32 // semaphore for readers to wait for completing writers
    readerCount int32  // number of pending readers
    readerWait  int32  // number of departing readers
}

讀寫鎖里面內(nèi)置了一個互斥鎖。


互斥鎖的使用

func (m *Mutex) Lock()
func (m *Mutex) Unlock()

互斥鎖提供兩個API,Lock和Unlock,按字面意思一個是加鎖,另一個是釋放鎖。

  • 當(dāng)一個互斥鎖被Lock了以后,任何goroutines(不管是不是當(dāng)前Lock了這個鎖的goroutine)試圖再Lock這個鎖時都會被掛起,直到鎖被釋放Unlock。
  • 互斥鎖不是可重入的,也就是說鎖被一個goroutine Lock了之后,當(dāng)前goroutine也不能再對當(dāng)前鎖進行Lock操作,否則也會被掛起。(如果當(dāng)前環(huán)境只有一個活動goroutine,go會報死鎖錯誤 fatal error: all goroutines are asleep - deadlock!)
  • 因為go語言的Mutex并不和任何goroutine相關(guān)聯(lián),這需要對比Linux pthread里面的線程鎖的差異
  • 正因為Mutex并不與特定的goroutine相關(guān)聯(lián),所以一個互斥鎖被一個goroutine鎖住了,它可以在另外一個goroutine里面被解鎖Unlock。

總之

  1. 一個已經(jīng)鎖住的互斥鎖不能再次被鎖住,不管是同一個還是另一個goroutine
  2. 一個已經(jīng)釋放的互斥鎖也不能再次被釋放,不管是同一個還是另一個goroutine

讀寫鎖

    func (rw *RWMutex) RLock()
    func (rw *RWMutex) RUnlock()
    func (rw *RWMutex) Lock()
    func (rw *RWMutex) Unlock()

和互斥鎖相比較,讀寫鎖增加了兩個RLock()/RUnLock(),我們把它定義為讀鎖,另一個相對就叫寫鎖。
讀寫鎖和pthread的的讀寫鎖類似,可以多人同時鎖住讀鎖,但是寫鎖只能有一個人鎖住。

  • 當(dāng)讀寫鎖被一個goroutine加了讀鎖,此讀寫鎖還能被任何goroutine加讀鎖,但不能加寫鎖(會等待直到所有讀鎖釋放)
  • 當(dāng)讀寫鎖被一個goroutine加了寫鎖,任何goroutine將不能再對此讀寫鎖加鎖,不管是加讀鎖還是加寫鎖
  • 當(dāng)讀寫鎖被一個goroutine加了讀鎖,在同一個gorounte內(nèi),它不能再被加寫鎖,但可以加讀鎖;同樣
  • 當(dāng)讀寫鎖被一個goroutine加了寫鎖,在同一個gorounte內(nèi),它不能再被加讀鎖,加寫鎖也不能。

因為RWMutex和Mutex一樣并不與特定的goroutine相關(guān)聯(lián),所有的鎖操作并不區(qū)分是哪一個goroutine進來的請求,是同一個goroutine還是不同的goroutine一同對待。

總結(jié)一點

  1. goroutine并不是和unix的thread一個概念,他們不具有一一對應(yīng)關(guān)系。
  2. go語言的鎖也并不與任何特定的goroutine相關(guān)聯(lián),鎖并沒有記錄當(dāng)前是哪個goroutine鎖住了自己。

可能是因為既然goroutine并不直接相關(guān)聯(lián)與一個thread,同一個thread可能關(guān)聯(lián)到多個goroutine(請閱讀goroutine模型的文章),所以鎖無法確切地區(qū)分是哪一個thread,所以也沒有辦法做到關(guān)聯(lián)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容