关于向关闭的channel中发送数据的问题
来源:1-6 Go 语法背后的秘密
Dobby喵
2021-05-21 14:34:36
ch := make(chan int)
close(ch)
ch<-1
问题描述:
曹大代码如上,再用dlv调试的时候我发现上述代码好像一共调用了2次chansend方法,请问这个是什么逻辑呢。
尝试过的解决方式:
自己在顺着源码分析得时候,没能看懂相应得原因
1回答
程序启动的时候 gc 相关的也有一些 channel 操作,你可以用 dlv 的 bt 命令,看看当前的 chansend 是从哪里进去的,
(dlv) c > runtime.chansend() /usr/local/go/src/runtime/chan.go:142 (hits goroutine(4):1 total:1) (PC: 0x1004053) Warning: debugging optimized function 137: * sleep can wake up with g.param == nil 138: * when a channel involved in the sleep has 139: * been closed. it is easiest to loop and re-run 140: * the operation; we'll see that it's now closed. 141: */ => 142: func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { 143: if c == nil { 144: if !block { 145: return false 146: } 147: gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2) (dlv) bt 0 0x0000000001004053 in runtime.chansend at /usr/local/go/src/runtime/chan.go:142 1 0x0000000001004035 in runtime.chansend1 at /usr/local/go/src/runtime/chan.go:127 2 0x000000000101c0c3 in runtime.bgscavenge at /usr/local/go/src/runtime/mgcscavenge.go:236 3 0x000000000105a941 in runtime.goexit at /usr/local/go/src/runtime/asm_amd64.s:1373
你要调试的是 main 里的这一句,所以可以先进 main.main 函数,然后再在 chansend 上打断点,然后按 c(continue)
下面这种有 main.main 的才是你应该注意的操作位置:
(dlv) c > runtime.chansend() /usr/local/go/src/runtime/chan.go:142 (hits goroutine(1):1 total:3) (PC: 0x1004053) Warning: debugging optimized function 137: * sleep can wake up with g.param == nil 138: * when a channel involved in the sleep has 139: * been closed. it is easiest to loop and re-run 140: * the operation; we'll see that it's now closed. 141: */ => 142: func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { 143: if c == nil { 144: if !block { 145: return false 146: } 147: gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2) (dlv) bt 0 0x0000000001004053 in runtime.chansend at /usr/local/go/src/runtime/chan.go:142 1 0x0000000001004035 in runtime.chansend1 at /usr/local/go/src/runtime/chan.go:127 2 0x000000000105ee13 in main.main at ./cs.go:6 3 0x000000000102fdb8 in runtime.main at /usr/local/go/src/runtime/proc.go:203 4 0x000000000105a941 in runtime.goexit at /usr/local/go/src/runtime/asm_amd64.s:1373
相似问题
回答 2
回答 1
回答 1
回答 1
回答 2