Go 使用 channel 實現 CSP 模型。處理雙方僅關注通道和數據自己,無需理會對方身份和數量,以此實現結構性解耦。在各文宣中都有 「Don't communicate by sharing memory, share memory by communicating.」 這類說法。但這並不是鼓勵咱們不分場合,教條地使用 channel。 算法
在我看來,channel 多數時候適用於結構層面,而非單個區域的數據處理。原話中 「communicate」 本就代表一種 「message-passing」,而非 「lock-free」。因此,它並不是用來取代 mutex,各自有不一樣的使用場景。 安全
有關 channel 實現方式,可參考《Go 學習筆記》第五版,下卷《源碼剖析》。
從實現角度看,channel 算是一種很 「重」 的實現。在小粒度層面,其性能真算不得好。咱們可用一個常見示例測試一下:用 channel 實現併發安全的計數器,或序號生成器。 架構
性能測試結果代表,差別遠比想的要大得多。單就此例而言,還能夠用原子操做(atomic)進一步優化。 併發
若是說 channel 適用於結構層面解耦,那麼 mutex 則適合保護語句級別的數據安全。至於 atomic,雖然也可實現 lock-free 結構,但處理起來要複雜得多(好比 ABA 等問題),也未必就比 mutex 快不少。還有,sync.Mutex 本就沒有使用內核實現,而是像 Futex 那樣,直接在用戶空間以 atomic 操做完成,由於 runtime 沒有任何理由將剩餘 CPU 時間片還給內核。 性能
從沒一種技術或技巧適用於全部場合。不管是表達,或者選型,都不該該脫離實際場景(上下文)。另外,就本系列的優化技巧而言,除非真有必要,不然大可沒必要理會這些 「奇技淫巧」。至於擔憂可否適應將來變化,我以爲多餘。由於不管是架構、算法,亦或者是這些技巧,你本就應該有相應的機制確保在 「變化」 發生時第一時間獲知。再者說,技巧並不是照抄,無非多種思路而已。知其形,明其意,方爲正理。 學習
最新動態,請掃碼關注 測試