【问题标题】:Can't read from a channel in goroutine [duplicate]无法从goroutine中的通道读取[重复]
【发布时间】:2019-11-18 17:18:55
【问题描述】:

在这段代码中,创建了一个 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)
}

【问题讨论】:

    标签: go concurrency channel goroutine


    【解决方案1】:

    首先,缓冲区不是空的,因为你在上面发送了一个值:

    ch <- 1
    

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

    然后你启动一个 goroutine,main() 函数结束。这样,您的程序也结束了,它不会等待其他非主 goroutine 完成。详情请见No output from goroutine in Go。

    请注意,即使您在 main() 中注释掉发送操作也会发生同样的事情:您启动了一个 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

    【讨论】:

    • 谢谢!不过忘记注释掉问题中的 ch
    • @Gabriel 如果你注释掉发送,同样的事情:应用程序结束而不等待另一个 goroutine。
    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 2016-02-02
    • 2020-06-26
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多