无法从goroutine中的频道读取

时间:2019-07-09 07:44:38

标签: go concurrency channel goroutine

在这段代码中,创建了一个goroutine,并尝试从缓冲的通道中读取数据。

但是缓冲区是空的,应该阻塞接收者,但是没有。它将运行,但没有输出。

package main

import "fmt"

func fun(c chan int) {
    fmt.Println(<-c)
}

func main() {
    ch := make(chan int, 1)
    //ch <- 1
    go fun(ch)
}

1 个答案:

答案 0 :(得分:3)

首先,缓冲区不为空,因为您向其发送了一个值:

ch <- 1

此发送操作不会阻塞,因为通道已缓冲。

然后启动一个goroutine,main()函数结束。这样一来,您的程序也将结束,它不会等待其他非主要goroutine完成。有关详细信息,请参见No output from goroutine in Go

请注意,即使您在main()中注释掉send操作,也会发生同样的事情:启动goroutine,然后main()与您的应用程序一起结束:它不会等待其他goroutine。

要等待其他goroutine,通常使用sync.WaitGroup,如下所示:

var wg = &sync.WaitGroup{}

func fun(c chan int) {
    defer wg.Done()
    fmt.Println(<-c)
}

func main() {
    ch := make(chan int, 1)
    ch <- 1

    wg.Add(1)
    go fun(ch)
    wg.Wait()
}

然后将输出(在Go Playground上尝试):

1

有关详细信息,请参见Prevent the main() function from terminating before goroutines finish in Golang