Go 初體驗 - 併發與鎖.3 - 競態

競態,就是多個協程同時訪問臨界區,由併發而產生的數據不一樣步的狀態。併發

這個說的有點low,沒辦法,我就是這麼表達的,官方的請度娘。工具

先上代碼:3d

輸出:協程

爲什麼不是1000?就是由於競態,發生競態後,最終的輸出是以最後一個協程執行的結果爲準,但最後一個協程有必定的隨機性,不是先跑先完。blog

改一下代碼:隊列

輸出:同步

由於加了鎖,這1000個協程是按照隊列的順序執行12行,因此穩定輸出 final value of x 1000引用

再看:im

輸出:d3

照樣穩定輸出 final value of x 1000,由於信道的讀和寫都具備排他性,雖然不是鎖住臨界區,可是能起到讓後來的協程排隊的效果。

 

 

 

那麼這兩種狀況怎麼選擇呢? 引用一個大牛的話:

Mutex vs 信道

經過使用 Mutex 和信道,咱們已經解決了競態條件的問題。那麼咱們該選擇使用哪個?答案取決於你想要解決的問題。若是你想要解決的問題更適用於 Mutex,那麼就用 Mutex。若是須要使用 Mutex,無須猶豫。而若是該問題更適用於信道,那就使用信道。:)

因爲信道是 Go 語言很酷的特性,大多數 Go 新手處理每一個併發問題時,使用的都是信道。這是不對的。Go 給了你選擇 Mutex 和信道的餘地,選擇其中之一均可以是正確的。

整體說來,當 Go 協程須要與其餘協程通訊時,可使用信道。而當只容許一個協程訪問臨界區時,可使用 Mutex。

就咱們上面解決的問題而言,我更傾向於使用 Mutex,由於該問題並不須要協程間的通訊。因此 Mutex 是很天然的選擇。

個人建議是去選擇針對問題的工具,而別讓問題去將就工具。:)

相關文章
相關標籤/搜索