close chan
- close由發送端調用,在收到最後一個發送值後關閉管道(It should be executed only by the sender, never the receiver, and has the effect of shutting down the channel after the last sent value is received)
- close管道後,所有從管道的讀取會獲得元素對應類型的零值(any receive from c will succeed without blocking, returning the zero value for the channel element.)
package main
import (
"fmt"
"time"
)
func main() {
stop := make(chan struct{})
go func() {
select {
case _, ok := <-stop:
fmt.Println("stop 01: ", ok)
}
}()
go func() {
select {
case _, ok := <-stop:
fmt.Println("stop 02: ", ok)
}
}()
stop <- struct{}{}
close(stop)
time.Sleep(time.Second * 2)
_, ok := <-stop
fmt.Println("stop chan: ", ok)
}
stop 02: true
stop 01: false
stop chan: false
結論:chan中發送的值被第二個協程讀取,主協程和第一個協程的讀取都返回了bool的零值(false)
-
不允許給已關閉的chan發送值,見下例:
package main func main() { stop := make(chan struct{}) close(stop) stop <- struct{}{} }panic: send on closed channel
-
給chan發送值,只能被讀取一次
package main import ( "fmt" "time" ) func main() { stop := make(chan struct{}) go func() { select { case _, ok := <-stop: //stop = nil fmt.Println("stop 01: ", ok) } }() go func() { select { case _, ok := <-stop: fmt.Println("stop 02: ", ok) } }() stop <- struct{}{} time.Sleep(time.Second * 2) }stop 02: true
這裏因為只給chan發送了一個值,所以只會退出一個協程(隨機性)。