golang面试题:对未初始化的的chan进行读写,会怎么样?为何?

问题

未初始化的的 chan 进行读写,会怎么样?为何?golang

怎么答

读写未初始化chan 都会阻塞web

举例

1. 写未初始化的 chan
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),待会会提到。面试

2. 写读未初始化的 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

相关文章
相关标签/搜索