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

我创建了一个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 发送时处理新数据。


茅侃侃
浏览 100回答 2
2回答

梵蒂冈之花

我认为您遇到了僵局,因为您func2只消耗了1 个值ch,然后完成。然后其他func1goroutine 被卡住等待ch可以写入,他们不能这样做,因为ch在另一端没有其他 goroutine 可以读取。由于您希望func2从chuntil开始持续消耗值ch,因此您需要func2像这样创建一个循环:func func2(ch chan int) {&nbsp; &nbsp; fmt.Println("func2")&nbsp; &nbsp; for v := range ch {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(v)&nbsp; &nbsp; }}这将保持func2“活跃”并阅读,ch直到你在close(ch)其他地方做。在您的示例中关闭的适当位置ch可能在mainafter wg.Wait()。如果您想确保Println在程序完成之前看到所有语句的结果,您还应该使用一些同步机制来等待func2完成。否则main将立即结束,之后close(ch)可能会或可能不会在func2打印收到的每个值之前。一种常见的技术是“完成”通道。例如:func func2(ch chan int, done chan bool) {&nbsp; &nbsp; fmt.Println("func2")&nbsp; &nbsp; for v := range ch {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(v)&nbsp; &nbsp; }&nbsp; &nbsp; done <- true}并在main:done := make(chan bool)go func2(ch, done)...wg.Wait()close(ch)<-done使用chan struct{}(empty struct) 也很常见,因为空结构不需要内存。

蝴蝶不菲

您正在寻找的是一种在所有值都完成流式传输时关闭通道的干净方法。当新值出现时,您可以创建一个新通道并开始在此流式传输值。我就是这样做的,也许有帮助var wg sync.WaitGrouptoUpdate := make(chan *someType, BufferSize)for i := 0; i < BufferSize; i++ {&nbsp; &nbsp; go processEvents(toUpdate, &wg)}// // wait till all the checks have come backgo func(toUpdate chan * someType, group *sync.WaitGroup) {&nbsp; &nbsp; group.Wait()&nbsp; &nbsp; close(toCreate)}(toCreate, toUpdate, &wg)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go