目錄
先來看這樣一段**,所存在的問題:
var wg sync.waitgroup
var x int64
func main()
func f()
wg.done()
}這裡為什麼輸出是 12135(不同的機器結果不一樣),而不是20000。
因為 x 的賦值,總共分為三個步驟:取出x的值、計算x的結果、給x賦值。那麼由於對於f函式的呼叫採用了goroutine協程,所以存在資源競爭的問題,所以有賦值和計算過程中存在髒資料。對於此類的問題,可以採用互斥鎖解決:
互斥鎖是一種常用的控制共享資源訪問的方法,它能夠保證同時只有乙個goroutine可以訪問共享資源。go語言中使用sync包的mutex型別來實現互斥鎖。
var wg sync.waitgroup
var x int64
var lock sync.mutex
func ma程式設計客棧in()
func f()
wg.done()
}使用互斥鎖能夠保證同一時間有且只有乙個goroutine進入臨界區,其他的goroutine則在等待鎖;當互斥鎖釋放後,等待的goroutine才可以獲取鎖進入臨界區,多個goroutin同時等待乙個鎖時,喚醒的策略是隨機的。
互斥鎖是完全互斥的,但是有很多實際的場景下是讀多寫少的,當我們併發的去讀取乙個資源不涉及資源修改的時候是沒有必要加鎖的,這種場景下使用讀寫鎖是更好的一種選擇。讀寫鎖在go語言中使用sync包中的rwmutex型別。
讀寫鎖分為兩種:讀鎖和寫鎖。當乙個goroutine獲取讀鎖之後,其他的goroutine如果是獲取讀鎖會繼續獲得鎖,如果是獲取寫鎖就會等待;當乙個goroutine獲取寫鎖之後,其他的goroutine無論是獲取讀鎖還是寫鎖都會等待。
var (
x1 int64
wg1 sync.waitgroup
lock1 sync.mutex
rwlock sync.rwmutex
)func main()
for i:=0;i<10000;i++
wg1.wait()
fmt.println(time.now().sub(starttime))
// 互斥鎖用時: 973.9304ms
// 讀寫互斥鎖用時: 718.094ms
}func read() 程式設計客棧
func write()
互斥鎖和讀寫鎖
互斥鎖的型別 對資源的訪問是互斥的,即執行緒a對資源加鎖後,在a解鎖前,其他執行緒不能訪問這個加鎖的資源。互斥鎖的特點 多個執行緒訪問資源的時候是序列的 互斥鎖的使用步驟 建立乙個互斥鎖 pthread mutex t mutex 初始化這把鎖 pthread mutex init mutex,nu...
互斥鎖機制,互斥鎖與讀寫鎖區別
互斥鎖 mutex,用於保證在任何時刻,都只能有乙個執行緒訪問該物件。當獲取鎖操作失敗時,執行緒會進入睡眠,等待鎖釋放時被喚醒 讀寫鎖 rwlock,分為讀鎖和寫鎖。處於讀操作時,可以允許多個執行緒同時獲得讀操作。但是同一時刻只能有乙個執行緒可以獲得寫鎖。其它獲取寫鎖失敗的執行緒都會進入睡眠狀態,直...
go 互斥鎖實現原理
目錄2.加解鎖過程 3.自旋過程 4.mutex模式 5.woken狀態 6.為什麼重複解鎖要panic go中通過mutex來實現對互斥資源的鎖定 go type mutex struce下圖展示了mutex的記憶體布局 協程之間搶鎖的過程實際上是給locked賦值1的過程,能給locked賦值為...