Go語(yǔ)言中sync.Mutex的使用方法
背景
多個(gè)協(xié)程操作中經(jīng)常出現(xiàn)臟讀寫(xiě)的情況,這種情況下需要使用互斥鎖,保證在對(duì)協(xié)程共享區(qū)域操作的原子性。
如下示例:
啟動(dòng)了 100個(gè)協(xié)程,每個(gè)協(xié)程累加 100 次,在沒(méi)有臟讀寫(xiě)的情況下,最后結(jié)果應(yīng)該是 100 * 100 = 10000
package main
import (
"fmt"
"sync"
)
func main() {
var count = 0
var wg sync.WaitGroup
wg.Add(100)
for i :=0; i< 100; i++ {
go func(){
defer wg.Done()
for j := 0; j< 100; j ++ {
count ++
}
}()
}
wg.Wait()
fmt.Println(count)
}
但是實(shí)際結(jié)果一直小于 10000

互斥鎖
count ++ 操作, 分為三個(gè)步驟
在協(xié)程的共享區(qū)域取出 count 當(dāng)前值
當(dāng)前值加一
加一后的值寫(xiě)回協(xié)程共享區(qū)域
這時(shí)需要使用互斥鎖, 來(lái)保證對(duì) count++ 的三個(gè)操作過(guò)程中沒(méi)有其他協(xié)程進(jìn)行讀寫(xiě)。
Go的Sync 包提供了Mutex, 讀寫(xiě)互斥的鎖, 來(lái)保證只有一個(gè)協(xié)程對(duì)數(shù)據(jù)進(jìn)行讀寫(xiě)操作。 以保證 count++操作的原子性
如下示例:
package main
import (
"fmt"
"sync"
)
func main() {
var count = 0
// 聲明Mutex變量
var mu sync.Mutex
var wg sync.WaitGroup
wg.Add(100)
for i :=0; i< 100; i++ {
go func(){
defer wg.Done()
for j := 0; j< 100; j ++ {
// 添加鎖
mu.Lock()
count ++
// 解鎖
mu.Unlock()
}
}()
}
wg.Wait()
fmt.Println(count)
}
在mu.Lock() 和mu.Unlock() 之間的代碼可以保證在操作只會(huì)被一個(gè)協(xié)程執(zhí)行。這樣執(zhí)行結(jié)果就是 10000 了

注意
mu.Lock() 和mu.Unlock() 必須成對(duì)出現(xiàn),在忘掉 Unlock 的情況下,鎖獲取后永遠(yuǎn)不會(huì)得到釋放,其他 的線(xiàn)程/協(xié)程會(huì)永遠(yuǎn)處于阻塞狀態(tài),永遠(yuǎn)獲取不到鎖,在忘掉 Lock 的情況下,直接 Unlock 一個(gè)未加鎖的 Mutex,會(huì)導(dǎo)致程序 panic。
到此這篇關(guān)于Go語(yǔ)言中sync.Mutex的使用方法的文章就介紹到這了,更多相關(guān)Go sync.Mutex內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- GO語(yǔ)言協(xié)程互斥鎖Mutex和讀寫(xiě)鎖RWMutex用法實(shí)例詳解
- 一文詳解Go語(yǔ)言中Mutex互斥鎖
- 一文帶你讀懂Golang?sync包之sync.Mutex
- golang中sync.Mutex的實(shí)現(xiàn)方法
- golang基于Mutex實(shí)現(xiàn)可重入鎖
- Go中sync.Mutex 加鎖失效的問(wèn)題解決
- Golang?Mutex錯(cuò)過(guò)會(huì)后悔的重要知識(shí)點(diǎn)分享
- golang RWMutex讀寫(xiě)鎖實(shí)現(xiàn)讀共享寫(xiě)?yīng)氄嫉墓δ苁纠?/a>
- Golang中Mutex 自旋的實(shí)現(xiàn)
相關(guān)文章
go語(yǔ)言程序cpu過(guò)高問(wèn)題排查的方法詳解
使用golang進(jìn)行復(fù)雜的組合運(yùn)算,導(dǎo)致CPU占用率非常高,下面這篇文章主要給大家介紹了關(guān)于go語(yǔ)言程序cpu過(guò)高問(wèn)題排查的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04
Go語(yǔ)言中的空值(nil)與零值(zerovalue)區(qū)別詳解
在Go語(yǔ)言中,空值(nil)和零值(zero value)是兩個(gè)不同的概念,它們?cè)谡Z(yǔ)義、使用場(chǎng)景以及實(shí)際的編程實(shí)踐中有著明顯的區(qū)別,理解這兩者的差異對(duì)于編寫(xiě)清晰、健壯的Go代碼至關(guān)重要,需要的朋友可以參考下2024-06-06
golang敏感詞過(guò)濾的實(shí)現(xiàn)
本文主要介紹了golang敏感詞過(guò)濾的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
Go語(yǔ)言使用slices包輕松實(shí)現(xiàn)排序功能
在 Go 語(yǔ)言開(kāi)發(fā)中,對(duì)數(shù)據(jù)進(jìn)行排序是常見(jiàn)的需求,Go 1.18 版本引入的 slices包提供了簡(jiǎn)潔高效的排序解決方案,支持內(nèi)置類(lèi)型和用戶(hù)自定義類(lèi)型的排序操作,本文將通過(guò)具體示例,詳細(xì)介紹如何使用 slices包實(shí)現(xiàn)排序及相關(guān)功能,需要的朋友可以參考下2025-05-05

