如何優雅的關閉Golang Channel?

Channel關閉原則

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

暴力關閉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在語法上就完全被禁止使用了。3d

優雅的關閉channel的方法

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

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


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

多個生產者,多個消費者

相關文章
相關標籤/搜索