Go Wiki:使用 sync.Mutex 還是通道?
Go 的座右銘之一是「透過溝通來共用記憶體,不要透過共用記憶體來溝通。」
話雖如此,Go 確實在 sync 套件 中提供了傳統的鎖定機制。大多數鎖定問題都可以使用通道或傳統鎖定來解決。
那麼您應該使用哪一種?
使用最具表達力或最簡單的那一種。
Go 新手的常見錯誤是過度使用通道和 goroutine,僅僅是因為它可行,或者因為它很有趣。如果您發現 sync.Mutex
最適合您的問題,請不要害怕使用它。Go 務實地讓您使用最能解決您問題的工具,而不是強迫您採用一種程式碼風格。
不過,作為一般指南
通道 | 互斥鎖 |
---|---|
傳遞資料的所有權, 分配工作單元, 傳達非同步結果 | 快取, 狀態 |
如果您發現 sync.Mutex 鎖定規則變得過於複雜,請自問使用通道是否會更簡單。
等待群組
另一個重要的同步原語是 sync.WaitGroup。這些允許合作的 goroutine 在獨立繼續進行之前,共同等待一個臨界事件。這通常在兩種情況下很有用。
首先,在「清理」時,可以使用 sync.WaitGroup 來確保所有 goroutine(包括主 goroutine)在乾淨地終止之前等待。
第二個更通用的情況是一個循環演算法,它涉及一組 goroutine,它們獨立工作一段時間,然後全部等待一個屏障,然後再獨立繼續進行。此模式可能會重複多次。資料可能會在屏障事件中交換。此策略是 大規模同步並行 (BSP) 的基礎。
通道通訊、互斥鎖和等待群組是互補的,可以組合使用。
更多資訊
- Effective Go 中的通道:https://go.dev.org.tw/doc/effective_go#channels
- sync 套件:https://pkg.go.dev/sync/
此內容是 Go Wiki 的一部分。