为什么从 nil 通道读取会增加 Goroutines 的数量?

我改编了以下示例,说明了由于从 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?


智慧大石
浏览 79回答 1
1回答

慕侠2389804

当你的应用程序启动时,已经有一个 goroutine 运行该main()函数。如果不初始化ch通道,它将保持通道的零值nil。规格: 接收运算符:从nil通道接收永远阻塞。因此,如果通道为nil,则启动的 goroutine 将永远不会结束。所以你将有 2 个 goroutine:本身的maingoroutine 和你启动的 goroutine。如果你用 1 个缓冲区初始化通道并在其上发送一个值,那么你也会在“一小段时间”内拥有 2 个 goroutine,但启动的 goroutine 可以从中接收一个值,然后立即结束。所以只剩下一个 goroutine,即maingoroutine。
打开App,查看更多内容
随时随地看视频慕课网APP