原文:https://github.com/golang/go/wiki/MutexOrChannel
用sync.Mutex還是channel
go有一句格言是“用通信來共享存儲无宿,不要用共享存儲來通信”麦锯。
即便如此,go還是在sync包中提供了傳統(tǒng)的鎖機制符糊。而大多數(shù)鎖的問題都可以通過channel或者傳統(tǒng)的lock方式解決铭若。
所以你應(yīng)該用哪種方式呢?
根據(jù)場景户矢,用最富有表達力虏肾、最簡單的方式冠蒋。
go新手們常犯的一個錯誤就是對goroutine和channel的過度使用羽圃,僅僅是因為可以這么用或者說用起來更好玩。如果用sync.Mutex能更漂亮的解決你的問題抖剿,不要害怕去使用它朽寞。go提倡的是務(wù)實,即用最適合解決你問題的方法斩郎,不要拘泥于某種編碼手段脑融。
下面給出一個通用的法則:
channel | mutex |
---|---|
傳遞數(shù)據(jù)的控制權(quán) | 緩存 |
下發(fā)任務(wù) | 狀態(tài) |
傳遞異步調(diào)用結(jié)果 |
當(dāng)你發(fā)現(xiàn)使用mutex規(guī)則過于復(fù)雜時,也許用channel會更適合孽拷。
Wait Group
另一個非常重要的同步手段是sync.WaitGroup吨掌。它能使協(xié)同工作的一組goroutines共同等待一個閾值事件,之后再繼續(xù)獨立運行。這在以下兩種情況下非常有用膜宋。
首先窿侈,在cleaning up時,它可以讓所有g(shù)oroutine包括main goroutine在clean完成之前秋茫,都一起等待史简。
其次,是當(dāng)一組各自獨立的goroutine共同完成一個循環(huán)算法時肛著,讓這些goroutines共同等待一個臨界事件圆兵,然后再次獨立執(zhí)行下去。這個過程可以是被重復(fù)執(zhí)行的枢贿,數(shù)據(jù)在臨界事件中可以被交換殉农。這個策略是bsp的基礎(chǔ)。
Channel局荚、Mutex超凳、WaitGroup互相補充,是可以被組合使用的耀态。