为了账号安全,请及时绑定邮箱和手机立即绑定

我怎样才能拥有一个等待来自多个其他人的值的 goroutine 函数?

我怎样才能拥有一个等待来自多个其他人的值的 goroutine 函数?

Go
茅侃侃 2022-05-18 10:40:42
我创建了一个Go 操场示例来说明我在说什么。在示例中,我创建了一个 goroutine,func2,我只想通过它的通道等待输入,并在它到达后打印值。func func2(ch chan int) {    fmt.Println("func2")    v:=<-ch    fmt.Println(v)}然后,在一个循环中,我为另一个函数创建 goroutine,这些是 WaitGroup 的一部分。func func1(ch chan int, wg *sync.WaitGroup) {    fmt.Println("func1")    ch <- 11032    wg.Done()}总的来说,我等待 WaitGroup。我遇到了僵局,我不知道如何解决它。很清楚我想要实现的目标,我希望 func2 在我调用它后作为线程保持打开状态,以处理 n 个值,其中 n 是我为 func1 调用的 goroutine 的数量。我考虑在 func2 中使用 WaitGroup Wait,但我不希望它阻塞,因为它需要在 func1 发送时处理新数据。
查看完整描述

2 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

我认为您遇到了僵局,因为您func2只消耗了1 个值ch,然后完成。然后其他func1goroutine 被卡住等待ch可以写入,他们不能这样做,因为ch在另一端没有其他 goroutine 可以读取。


由于您希望func2从chuntil开始持续消耗值ch,因此您需要func2像这样创建一个循环:


func func2(ch chan int) {

    fmt.Println("func2")

    for v := range ch {

        fmt.Println(v)

    }

}

这将保持func2“活跃”并阅读,ch直到你在close(ch)其他地方做。在您的示例中关闭的适当位置ch可能在mainafter wg.Wait()。


如果您想确保Println在程序完成之前看到所有语句的结果,您还应该使用一些同步机制来等待func2完成。否则main将立即结束,之后close(ch)可能会或可能不会在func2打印收到的每个值之前。


一种常见的技术是“完成”通道。例如:


func func2(ch chan int, done chan bool) {

    fmt.Println("func2")

    for v := range ch {

        fmt.Println(v)

    }

    done <- true

}

并在main:


done := make(chan bool)

go func2(ch, done)

...

wg.Wait()

close(ch)

<-done

使用chan struct{}(empty struct) 也很常见,因为空结构不需要内存。


查看完整回答
反对 回复 2022-05-18
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

您正在寻找的是一种在所有值都完成流式传输时关闭通道的干净方法。当新值出现时,您可以创建一个新通道并开始在此流式传输值。我就是这样做的,也许有帮助


var wg sync.WaitGroup


toUpdate := make(chan *someType, BufferSize)


for i := 0; i < BufferSize; i++ {

    go processEvents(toUpdate, &wg)

}


// // wait till all the checks have come back

go func(toUpdate chan * someType, group *sync.WaitGroup) {

    group.Wait()

    close(toCreate)

}(toCreate, toUpdate, &wg)


查看完整回答
反对 回复 2022-05-18
  • 2 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号