Go 初體驗 併發與鎖 3 競態

2022-02-08 15:45:50 字數 1053 閱讀 7309

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

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

先上**:

輸出:

為何不是1000?就是因為競態,發生競態後,最終的輸出是以最後乙個協程執行的結果為準,但最後乙個協程有一定的隨機性,不是先跑先完。

改一下**:

輸出:

因為加了鎖,這1000個協程是按照佇列的順序執行12行,所以穩定輸出 final value of x 1000

再看:輸出:

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

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

通過使用 mutex 和通道,我們已經解決了競態條件的問題。那麼我們該選擇使用哪乙個?答案取決於你想要解決的問題。如果你想要解決的問題更適用於 mutex,那麼就用 mutex。如果需要使用 mutex,無須猶豫。而如果該問題更適用於通道,那就使用通道。:)

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

總體說來,當 go 協程需要與其他協程通訊時,可以使用通道。而當只允許乙個協程訪問臨界區時,可以使用 mutex。

就我們上面解決的問題而言,我更傾向於使用 mutex,因為該問題並不需要協程間的通訊。所以 mutex 是很自然的選擇。

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

併發與競態

linux是乙個多工的作業系統,在多個程序同時執行時,就有可能為了競爭同乙個資源發生堵塞。以下是解決的幾種方法 1 訊號量 declare mutex sem if down interruptible sem critical section up sem 2 完成量 declare comple...

併發與競態及解決途徑

併發與競態及解決途徑 併發 concurrency 是指多個執行單元同時 並行的被執行,而併發執行單元對共享資源的訪問很容導致競態 race condition 併發與競態發生的條件 對稱多處理器 smp 的多個cpu 單cpu內程序與搶占它的程序 中斷與程序之間。解決併發與競態的途徑 訪問共享資源...

GO精髓 goroutine併發安全與鎖

1.互斥鎖 互斥鎖是對共享資源進行控制,在併發情況下只允許乙個對其操作 乙個協程訪問時其他的都不能訪問 var count 0 var wg sync.waitgroup var mutex sync.mutex 宣告乙個互斥鎖 func test func main wg.wait 2.讀寫互斥鎖...