go-鎖機制

Golang中的鎖機制主要包含互斥鎖和讀寫鎖

互斥鎖

互斥鎖是一種簡單的加鎖的方法來控制對共享資源的訪問,互斥鎖只有兩種狀態(tài),即上鎖( lock )和解鎖( unlock )路狮。

func mutex() { 
var mu
sync.Mutex mu.Lock() 
fmt.Println("locked")
mu.Unlock() 
}

defer實現(xiàn)

func mutex() {
var mu 
sync.Mutex mu.Lock() 
defer mu.Unlock() 
fmt.Println("locked")
 }

【互斥鎖的特點】:

  1. 原子性:把一個互斥量鎖定為一個原子操作僵驰,這意味著操作系統(tǒng)(或pthread函數(shù)庫)保證了如果一個線程鎖定了一個互斥量,沒有其他線程在同一時間可以成功鎖定這個互斥量几蜻;

  2. 唯一性:如果一個線程鎖定了一個互斥量千康,在它解除鎖定之前嫩痰,沒有其他線程可以鎖定這個互斥量钞艇;

  3. 非繁忙等待:如果一個線程已經(jīng)鎖定了一個互斥量啄寡,第二個線程又試圖去鎖定這個互斥量,則第二個線程將被掛起(不占用任何cpu資源)哩照,直到第一個線程解除對這個互斥量的鎖定為止挺物,第二個線程則被喚醒并繼續(xù)執(zhí)行,同時鎖定這個互斥量飘弧。

  4. 互斥鎖是開箱即用的识藤,只需要申明sync.Mutex即可直接使用

  5. 互斥鎖應(yīng)該是成對出現(xiàn),在同步語句不可以再對鎖加鎖眯牧,看下面的示例:

func mutex() { 
var mu 
sync.Mutex mu.Lock() 
fmt.Println("parent locked") 
mu.Lock() 
fmt.Println("sub locked") 
mu.Unlock() 
mu.Unlock()
}

此時則會出現(xiàn)fatal error: all goroutines are asleep - deadlock!錯誤

讀寫鎖

讀寫鎖和互斥鎖不同之處在于蹋岩,可以分別針對讀操作和寫操作進行分別鎖定赖草,這樣對于性能有一定的提升学少。 讀寫鎖,對于多個寫操作秧骑,以及寫操作和讀操作之前都是互斥的這一點基本等同于互斥鎖版确。 但是對于同時多個讀操作之前卻非互斥關(guān)系,這也是相讀寫鎖性能高于互斥鎖的主要原因乎折。

  • 特點
    開箱即用
    var rwm = sync.RWMutex
  • 寫鎖定和寫解鎖
    rwm.Lock()
    rwm.Unlock()
  • 讀鎖定和讀解鎖
    rwm.RLock()
    rwm.RUnlock()
  • 讀寫鎖的讀鎖和寫鎖不能交叉相互解鎖绒疗,否則會發(fā)生panic
func rwMutex() {
 var rwm sync.RWMutex
 rwm.Lock()
 fmt.Println("locked")
 rwm.RUnlock()
}
  • 對于讀寫鎖,同一資源可以同時有多個讀鎖定

在goroutine中骂澄,寫解鎖會試圖喚醒所有想要進行讀鎖定而被阻塞的goroutine吓蘑。

而讀解鎖會在已無任何讀鎖定的情況下,試圖喚醒一個想進行寫鎖定而被阻塞的goroutine。

func rwMutex() {
 var rwm sync.RWMutex

 for i := 0; i <= 2; i++ {
 go func(i int) {
 fmt.Printf("go(%d) start lock\n", i)
 rwm.RLock()
 fmt.Printf("go(%d) locked\n", i)
 time.Sleep(time.Second * 2)
 rwm.RUnlock()
 fmt.Printf("go(%d) unlock\n", i)
 }(i)
 }
 // 先sleep一小會磨镶,保證for的goroutine都會執(zhí)行
 time.Sleep(time.Microsecond * 100)
 fmt.Println("main start lock")
 // 當(dāng)子進程都執(zhí)行時溃蔫,且子進程所有的資源都已經(jīng)Unlock了
 // 父進程才會執(zhí)行
 rwm.Lock()
 fmt.Println("main locked")
 time.Sleep(time.Second)
 rwm.Unlock()
}

參考

互斥鎖、條件鎖琳猫、讀寫鎖以及自旋鎖:https://www.zhihu.com/question/66733477
https://www.cnblogs.com/cangqinglang/p/13328217.html
https://laravelacademy.org/post/19901.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伟叛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子脐嫂,更是在濱河造成了極大的恐慌统刮,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件账千,死亡現(xiàn)場離奇詭異侥蒙,居然都是意外死亡,警方通過查閱死者的電腦和手機匀奏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門辉哥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人攒射,你說我怎么就攤上這事醋旦。” “怎么了会放?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵饲齐,是天一觀的道長。 經(jīng)常有香客問我咧最,道長捂人,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任矢沿,我火速辦了婚禮滥搭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捣鲸。我一直安慰自己瑟匆,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布栽惶。 她就那樣靜靜地躺著愁溜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪外厂。 梳的紋絲不亂的頭發(fā)上冕象,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音汁蝶,去河邊找鬼渐扮。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的墓律。 我是一名探鬼主播意荤,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼只锻!你這毒婦竟也來了玖像?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤齐饮,失蹤者是張志新(化名)和其女友劉穎捐寥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祖驱,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡握恳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捺僻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片乡洼。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖匕坯,靈堂內(nèi)的尸體忽然破棺而出束昵,到底是詐尸還是另有隱情,我是刑警寧澤葛峻,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布锹雏,位于F島的核電站,受9級特大地震影響术奖,放射性物質(zhì)發(fā)生泄漏礁遵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一采记、第九天 我趴在偏房一處隱蔽的房頂上張望佣耐。 院中可真熱鬧,春花似錦唧龄、人聲如沸兼砖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掖鱼。三九已至然走,卻和暖如春援制,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芍瑞。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工晨仑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓洪己,卻偏偏與公主長得像妥凳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子答捕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容