The Channel Closing Prirciple
- 在沒有修改channel的狀態時, 此時沒有一個簡單通用的方式可以去檢查channel 是否關閉
- 關閉一個 close的 channel會發生 panic.
將值發送到一個關閉的channel 會發生panic
不要在接收端關閉 channel
- 如果有多個發送端, 也不要在發送端關閉 channel
- 只有一個發送端, 才在發送端關閉 channel
- 不要關閉已關閉的 channel
- 不要送值到已關閉的 channel
- 有方向的 channel 不可被關閉
| No | Situation | dataCh | stopCh | toStop | closing | closed | middle layer |
|---|---|---|---|---|---|---|---|
| 01 | M Receivers 1 Sender | 從 Sender 關閉 | x | x | x | x | x |
| 02 | 1 Receiver N Senders | 不必關閉 | Receiver: Close(stopCh) | x | x | x | x |
| 03 | M Receivers N Senders | 不必關閉 | 引用 moderator: 角色來關閉額外的訊號通到 close(stopCh) | 能讓任何 receiver 和 sender 閉數據通道 -> 發送訊號到 toStop channel select {case toStop <- "sender#" + id:default:} |
x | x | x |
| 04 | M Receivers 1 Sender Closed By 3Party | Sender 收到 stop() 發出的 closing 信號後, close(dataCh) |
x | x | 第三方 goroutine call stop() function stop := func() {select {case closing <- struct{}{}:<-closedcase <-closed:}} |
Sender 收到 stop() 發出的 closing 信號 -> return -> run defer function close(closed);close(dataCh); |
x |
| 05 | M Receivers N Senders Closed By 3Party | 在 middle layer close(dataCh) | x | x | third party 呼叫 stop function: 發出 closing <- by | 在 middle layer close(closed) | 需要藉由 middle layer 將 N 個 Sender, 轉換成 1 個 sender 讓此情境變成類似成 4.1: M receivers and 1 Sender, 由sender close dataCh channel |
Channel 操作
| 操作 | nil channel var ch chan int |
closed channel | not closed channel & not nil channel |
|---|---|---|---|
關閉Channel, close(ch) |
panic | panic | success close |
發送值到channel, ch<- |
block | panic | block or success |
從channel接收值, <-ch |
block | read zero value | block or success |
Read from channel
| 操作 | channel 狀態 | result | Sample |
|---|---|---|---|
Read <-ch |
nil | block | Link |
Read <-ch |
open and not nil | 輸出值 | |
Read <-ch |
open and nil | block | |
Read <-ch |
closed | read zero value | Link |
Read <-ch |
唯讀的channel <-ch |
編譯錯誤 | Link |
Wirte to channel
| 操作 | channel 狀態 | result | Sample |
|---|---|---|---|
Write ch<- |
nil | block | Link |
Write ch<- |
open and not nil | block | |
Write ch<- |
open and nil | 寫入值 | |
Write ch<- |
closed | panic | |
Write ch<- |
唯寫的channel ch<- |
編譯錯誤 | Link |
Close channel
| 操作 | channel 狀態 | result | Sample |
|---|---|---|---|
Close close(ch) |
nil | panic | |
Close close(ch) |
open and not nil | 關閉channel, 讀取成功.直到channel耗盡.然後讀取到 default value | |
Close close(ch) |
open and nil | 關閉channel, 讀取到Sender的default value | |
Close close(ch) |
closed | panic | |
Close close(ch) |
唯讀的channel <-ch |
編譯錯誤 | Linkg |