go程序启动时,runtime会自己创建一个channel并关闭吗?如果是,这个过程中都做了哪些工作呢?

来源:1-2 新加入的同学必看!!!

DarkPrince2

2021-05-22 16:55:09

第二课的作业,我在使用dlv调试关闭值为nil的chan时,在runtime.closechan处打断点,第一次运行到函数的地方,打印参数c的值不是nil,请问是go程序在启动时,会使用runtime自己创建一个chan并关闭吗?

http://img.mukewang.com/climg/60a8c68b090132b435820966.jpg


以上调试的代码是:

[root@f0391391e8a2 sendtoNil]# cat -n send_to_nil.go

     1 package main

     2

     3 func main() {

     4 var ch chan int

     5 close(ch)

     6 ch <- 1

     7 }


写回答

1回答

Xargin

2021-05-22

[root@0783a24aec92 home]# dlv debug ch.go
Type 'help' for list of commands.
(dlv) b closechan
Breakpoint 1 (enabled) set at 0x404b03 for runtime.closechan() /usr/local/go/src/runtime/chan.go:340
(dlv) c
> runtime.closechan() /usr/local/go/src/runtime/chan.go:340 (hits goroutine(1):1 total:1) (PC: 0x404b03)
Warning: debugging optimized function
   335:		src := sg.elem
   336:		typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.size)
   337:		memmove(dst, src, t.size)
   338:	}
   339:
=> 340:	func closechan(c *hchan) {
   341:		if c == nil {
   342:			panic(plainError("close of nil channel"))
   343:		}
   344:
   345:		lock(&c.lock)
(dlv) bt
0  0x0000000000404b03 in runtime.closechan
   at /usr/local/go/src/runtime/chan.go:340
1  0x0000000000430b74 in runtime.main
   at /usr/local/go/src/runtime/proc.go:192
2  0x000000000045b7c1 in runtime.goexit
   at /usr/local/go/src/runtime/asm_amd64.s:1373
(dlv) frame 1
> runtime.closechan() /usr/local/go/src/runtime/chan.go:340 (hits goroutine(1):1 total:1) (PC: 0x404b03)
Warning: debugging optimized function
Frame 1: /usr/local/go/src/runtime/proc.go:192 (PC: 430b74)
   187:			cgocall(_cgo_notify_runtime_init_done, nil)
   188:		}
   189:
   190:		doInit(&main_inittask)
   191:
=> 192:		close(main_init_done)
   193:
   194:		needUnlock = false
   195:		unlockOSThread()
   196:
   197:		if isarchive || islibrary {
(dlv) l
Goroutine 1 frame 1 at /usr/local/go/src/runtime/proc.go:192 (PC: 0x430b74)
   187:			cgocall(_cgo_notify_runtime_init_done, nil)
   188:		}
   189:
   190:		doInit(&main_inittask)
   191:
=> 192:		close(main_init_done)
   193:
   194:		needUnlock = false
   195:		unlockOSThread()
   196:
   197:		if isarchive || islibrary {
(dlv) frame 0
> runtime.closechan() /usr/local/go/src/runtime/chan.go:340 (hits goroutine(1):1 total:1) (PC: 0x404b03)
Warning: debugging optimized function
Frame 0: /usr/local/go/src/runtime/chan.go:340 (PC: 404b03)
   335:		src := sg.elem
   336:		typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.size)
   337:		memmove(dst, src, t.size)
   338:	}
   339:
=> 340:	func closechan(c *hchan) {
   341:		if c == nil {
   342:			panic(plainError("close of nil channel"))
   343:		}
   344:
   345:		lock(&c.lock)
(dlv) bt
0  0x0000000000404b03 in runtime.closechan
   at /usr/local/go/src/runtime/chan.go:340
1  0x0000000000430b74 in runtime.main
   at /usr/local/go/src/runtime/proc.go:192
2  0x000000000045b7c1 in runtime.goexit
   at /usr/local/go/src/runtime/asm_amd64.s:1373
(dlv) c
> runtime.closechan() /usr/local/go/src/runtime/chan.go:340 (hits goroutine(1):2 total:2) (PC: 0x404b03)
Warning: debugging optimized function
   335:		src := sg.elem
   336:		typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.size)
   337:		memmove(dst, src, t.size)
   338:	}
   339:
=> 340:	func closechan(c *hchan) {
   341:		if c == nil {
   342:			panic(plainError("close of nil channel"))
   343:		}
   344:
   345:		lock(&c.lock)
(dlv) bt
0  0x0000000000404b03 in runtime.closechan
   at /usr/local/go/src/runtime/chan.go:340
1  0x00000000004601c3 in main.main
   at ./ch.go:9
2  0x0000000000430ba8 in runtime.main
   at /usr/local/go/src/runtime/proc.go:203
3  0x000000000045b7c1 in runtime.goexit
   at /usr/local/go/src/runtime/asm_amd64.s:1373
(dlv)


1
harkPrince2
hp>谢谢曹大的思路引导,我再理解理解,dlv又熟练了不少,哈哈。

h021-05-22
共1条回复

Go高级工程师实战营

慕课网与 GoCN 社区官方联手打造,定义行业Go高级人才培养标准,4个月,快速晋升为P6+/D7级高级人才。

458 学习 · 266 问题

查看课程