对未初始化的的 chan
进行读写,会怎么样?为何?golang
读写未初始化的 chan
都会阻塞。web
package main
// 写未初始化的chan func main() { var c chan int c <- 1 } 复制代码
// 输出结果
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan send (nil chan)]: main.main() /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x36 复制代码
注意这个 chan send (nil chan)
,待会会提到。面试
package main
import "fmt" // 读未初始化的chan func main() { var c chan int num, ok := <-c fmt.Printf("读chan的协程结束, num=%v, ok=%v\n", num, ok) } 复制代码
// 输出结果
fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive (nil chan)]: main.main() /Users/admin18/go/src/code.byted.org/linzhaolun/repos/main.go:6 +0x46 复制代码
注意这个 chan receive (nil chan)
,待会也会提到。json
关于 chan
的面试题很是多,这个是比较常见的其中一个。但多问一句:为何对未初始化的 chan
就会阻塞呢?数组
1. 对于写的状况编辑器
//在 src/runtime/chan.go中
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { if c == nil { // 不能阻塞,直接返回 false,表示未发送成功 if !block { return false } gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2) throw("unreachable") } // 省略其余逻辑 } 复制代码
chan
此时是等于
nil
,当它不能阻塞的状况下,直接返回
false
,表示写
chan
失败
chan
能阻塞的状况下,则直接阻塞
gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)
, 而后调用
throw(s string)
抛出错误,其中
waitReasonChanSendNilChan
就是刚刚提到的报错
"chan send (nil chan)"
2. 对于读的状况学习
//在 src/runtime/chan.go中
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) { //省略逻辑... if c == nil { if !block { return } gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2) throw("unreachable") } //省略逻辑... } 复制代码
chan
此时是等于
nil
,当它不能阻塞的状况下,直接返回
false
,表示读
chan
失败
chan
能阻塞的状况下,则直接阻塞
gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)
, 而后调用
throw(s string)
抛出错误,其中
waitReasonChanReceiveNilChan
就是刚刚提到的报错
"chan receive (nil chan)"
中文、数字、英文字母
的字符串
本文使用 mdnice 排版ui