channel 总结
1. 声明和类型
ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
声明
双向:var ReadAndWriteChannel chan int
仅可读:var OnlyReadChannel <- chan int
仅可写:var OnlyWriteChannel chan <- int
初始化:
make(chan int) //坑:没有数据,读取阻塞,直至写入数据
make(chan int,100) // 容量 缓存 buffer
2. 操作
c := make(chan int)
读:i := <- c
写: c <- (7+2)
遍历: range c
关闭: close(c) 坑:关闭channel,可读,不可写(panic)
多值接收:判断是否关闭
x,ok := <-c //(ok == false 关闭)
阻塞情况一览
这些阻塞可能引起 deadlock——阻塞致死
-
无缓冲 channel:
- 需要接收和发送同时准备好,任意一方未准备好都会阻塞;
package main import ( "fmt" "time" ) func main() { c := make(chan int) //c <-1 不能放这里,recv没准备好 //fatal error: all goroutines are asleep - deadlock! // //goroutine 1 [chan send]: go func() { m := <-c fmt.Println(m) }() c <-1 time.Sleep(time.Second) }
-
有缓冲 channel:
- buffer 满了后 send 才会阻塞
- buffer 空了后 recv 会阻塞
-
关闭之后,send 阻塞
-
select 没有条件
fatal error: all goroutines are asleep - deadlock! goroutine 1 [select (no cases)]:
- 原文作者:战神西红柿
- 原文链接:https://tomatoares.github.io/posts/go/channel/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。