go - 为什么从 nil 通道读取会增加 Goroutine 的数量?
问题描述
我正在阅读此博客https://medium.com/golangspec/goroutine-leak-400063aef468,并修改了以下示例,说明了由于从 nil 通道接收而导致的 goroutine 泄漏:
package main
import (
"flag"
"fmt"
"runtime"
"time"
)
var initChannel bool
func 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?
解决方案
main()
当您的应用程序启动时,已经有一个运行该函数的 goroutine 。
如果您不初始化ch
通道,它将保持其用于通道的零值nil
。规格:接收运算符:
从
nil
通道接收永远阻塞。
有关详细信息,请参阅未初始化的通道如何表现?
所以如果 channel 是nil
,启动的 goroutine 将永远不会结束。因此,您将拥有 2 个 goroutine:main
goroutine 和您启动的 goroutine。
如果您使用 1 个缓冲区初始化通道并在其上发送一个值,那么您还将在“短时间内”拥有 2 个 goroutine,但启动的 goroutine 可以从中接收一个值然后立即结束。所以会剩下一个 goroutine,main
goroutine。
推荐阅读
- notepad++ - Notepad ++中如何删除没有字符串的行
- python - SSH 会话(Python 对象)贯穿剧本的整个生命周期
- shell - 使用 UNIX 如何将 3 个文件合并为一个文件,即(头文件、详细文件和尾文件)
- docker - Nginx 反向代理在本地主机上工作,但在 K8S 上不工作
- spring-boot - 将 spring 项目迁移到 2.x 时出现 UnsatisfiedDependencyException
- c# - 用字典中的列表填充 dataGridView?
- powershell - Reboot during Domain Controller promotion?
- react-native - How to use MQTT on React Native?
- jquery - addClass 在下次单击之前不会呈现
- angular - Ionic 4 and Angular 7 timeout and catchError cannot be found on a get request