如何安全close go 的channel
阿新 • • 發佈:2020-12-17
golang 在多協程下, 不清楚誰是 sender 誰是 recver 的時候, close(chan) 和 chan<-data 兩個都很容易報錯
原則:
//1 close 永遠和data分離, 不要close 還會發送或接受的 channel //2 close 永遠要做好 'close of closed channel' 錯誤的發生 //3 send (也就是 <- 操作) 永遠不要讓他出現 'send to a nil channel' 其實也就是第一點
那麼close 到底怎麼才能更安全,更正確的,解決呢?
單協程 直接close ,太low,我們不考慮,只考慮最複雜環境下的情況.
第一種方法暴力關閉channel ,只需要增加 recover() 就可以了
第二種方法 通過對變數加鎖,或者直接使用sync.Once 來控制 close 只有一次
第三種方法 建立兩個chan,一個永遠不close,只進行 無限 傳送, 單個接收; 一旦接收了 ,就關閉另外一個; 另外一個 返還給外部, 只判斷 close的情況,不進行傳送和直接close
第四種方法 比較簡單,總是 使用select就可以了,
done := make(chan struct{})
// 複雜環境下 併發 進行關閉 select{ case <-done: default: close(done) }
//複雜環境 併發 檢測是否關閉 select{ case <-done //關閉處理 return default: //沒有關閉的處理 }
https://zhuanlan.zhihu.com/p/32529039