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