首页 > 解决方案 > 无法从 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)
}

标签: goconcurrencychannelgoroutine

解决方案


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

ch <- 1

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

然后你启动一个 goroutine,main()函数结束。这样,您的程序也结束了,它不会等待其他非主 goroutine 完成。有关详细信息,请参阅Go 中的 goroutine 没有输出

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

要等待其他 goroutine,通常 async.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

有关详细信息,请参阅在 Golang 中防止 main() 函数在 goroutine 完成之前终止


推荐阅读