我改编了以下示例,说明了由于从 nil 通道接收而导致的 goroutine 泄漏:package mainimport ( "flag" "fmt" "runtime" "time")var initChannel boolfunc main() { flag.Parse() var ch chan int if initChannel { ch = make(chan int, 1) ch <- 1 } go func(ch chan int) { <-ch }(ch) c := time.Tick(1 * time.Second) for range c { fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine()) }}func init() { flag.BoolVar(&initChannel, "init", false, "initialize channel")}我注意到如果我用 运行它initChannel false,goroutine 的数量是 2:> go run main.go#goroutines: 2#goroutines: 2而如果我用 运行它true,数字是 1:> go run main.go --init#goroutines: 1#goroutines: 1然而,我不太明白为什么会出现这种情况。我只看到一个go语句,所以我希望在任何一种情况下都只有一个 goroutine。为什么从 nil 通道读取时有两个 goroutine?
1 回答
慕侠2389804
TA贡献1719条经验 获得超6个赞
当你的应用程序启动时,已经有一个 goroutine 运行该main()
函数。
如果不初始化ch
通道,它将保持通道的零值nil
。规格: 接收运算符:
从
nil
通道接收永远阻塞。
因此,如果通道为nil
,则启动的 goroutine 将永远不会结束。所以你将有 2 个 goroutine:本身的main
goroutine 和你启动的 goroutine。
如果你用 1 个缓冲区初始化通道并在其上发送一个值,那么你也会在“一小段时间”内拥有 2 个 goroutine,但启动的 goroutine 可以从中接收一个值,然后立即结束。所以只剩下一个 goroutine,即main
goroutine。
- 1 回答
- 0 关注
- 101 浏览
添加回答
举报
0/150
提交
取消