如何優雅的關閉Golang Channel?


Channel關閉原則

不要在消費端關閉channel,不要在有多個並行的生產者時對channel執行關閉操作。
也就是說應該只在[唯一的或者最后唯一剩下]的生產者協程中關閉channel,來通知消費者已經沒有值可以繼續讀了。只要堅持這個原則,就可以確保向一個已經關閉的channel發送數據的情況不可能發生。

暴力關閉channel的正確方法

如果想要在消費端關閉channel,或者在多個生產者端關閉channel,可以使用recover機制來上個保險,避免程序因為panic而崩潰。

func SafeClose(ch chan T) (justClosed bool) {
     defer func() {
        if recover() != nil {
            justClosed = false
        }
    }()
    close(ch)
    return true
}

使用這種方法明顯違背了上面的channel關閉原則,然后性能還可以,畢竟在每個協程只會調用一次SafeClose,性能損失很小。
同樣也可以在生產消息的時候使用recover方法。

禮貌關閉channel方法

還有不少人經常使用sync.Once來關閉channel,這樣可以確保只會關閉一次

同樣我們也可以使用sync.Mutex達到同樣的目的。

要知道golang的設計者不提供SafeClose或者SafeSend方法是有原因的,
他們本來就不推薦在消費端或者在並發的多個生產端關閉channel,
比如關閉只讀channel在語法上就徹底被禁止使用了。

優雅的關閉channel的方法

多個消費者,單個生產者.

多個生產者,單個消費者。


就上面這個例子,生產者同時也是退出信號channel的接受者,退出信號channel仍然是由它的生產者

多個生產者,多個消費者


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM