问题
对未初始化的的 chan
进行读写,会怎么样?为什么?
怎么答
读写未初始化的 chan
都会阻塞。
举例
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/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/repos/main.go:6 +0x46
注意这个 chan receive (nil chan)
,待会也会提到。
多问一句
关于 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)"
文章推荐:
- golang 面试题:reflect(反射包)如何获取字段 tag?为什么 json 包不能导出私有变量的 tag?
- golang 面试题:json 包变量不加 tag 会怎么样?
- golang 面试题:怎么避免内存逃逸?
- golang 面试题:简单聊聊内存逃逸?
- golang 面试题:字符串转成 byte 数组,会发生内存拷贝吗?
- golang 面试题:翻转含有
中文、数字、英文字母
的字符串 - golang 面试题:拷贝大切片一定比小切片代价大吗?
- golang 面试题:能说说 uintptr 和 unsafe.Pointer 的区别吗?
如果你想每天学习一个知识点?
本文使用 mdnice 排版
今天的文章golang面试题:对未初始化的的chan进行读写,会怎么样?为什么?分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21203.html