【问题标题】:How can I overlap goroutines?我怎样才能重叠 goroutine?
【发布时间】:2021-10-06 05:30:14
【问题描述】:

我有三个 gorutine,它们应该在某种循环中工作。例如,我有

go first() {
    // do some stuff
}
 
go second() {
    // do another kind of stuff
}

go third() {
    // do third kind of stuff
} 

他们必须这样工作: 第一个 - 第二个 - 第三个 - 第一个 - /等等等等/

我想我必须为此使用频道,但我想不出正确的方法。 如果我制作三个不同的频道 FirstToSecond, SeocndToThird, ThirdToFirst,然后当我运行程序时,我得到错误:

fatal error: all goroutines are asleep - deadlock!

但如果我去掉 ThirdToFirst,我就有了一个适当的循环,然后 gorutines 开始随机工作。

我当然错过了什么,但是什么?

带有两个 gorutine 的示例代码

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    wg.Add(2)

    ch1 := make(chan struct{})
    ch2 := make(chan struct{})

    go func() {
        for _, value := range []int{1, 3, 5} {
            <- ch1
            fmt.Println(value)
            ch2 <- struct{}{}    
        } 
        wg.Done()
    }()

    go func() {
        for _, value := range []int{2, 4, 6} {
            <- ch2
            fmt.Println(value)
            ch1 <- struct{}{}
        } 
        wg.Done()
    }()

    wg.Wait()
}

【问题讨论】:

  • 请提供minimal reproducible example,我们可以编译、运行和查看。谢谢
  • 这毫无意义。如果它们必须连续执行,请将它们全部放在一个例程中。看起来你只是想要for { first(); second(); third(); }
  • @rustyx 添加了示例。

标签: go concurrency channels


【解决方案1】:

如果您需要这样的排序,您可能会重新评估是否需要使用 goroutine。但是,您描述解决方案的方式是正确的:

go first() {
  for {
    <-ch1
    // do stuff
    ch2<-struct{}{}
  } 
}()

go second() {
  for {
    <-ch2
    // do stuff
    ch3<-struct{}{}
  } 
}()

go third() {
  for {
    <-ch3
    // do stuff
    ch1<-struct{}{}
  } 
}()

但是,这是一个循环设置,您必须在此结构之外启动第一个设置:

go first() {...}()
go second() {...}()
go third() {...} ()

// Start the first one
ch1<-struct{}{}

【讨论】:

  • 谢谢,这行得通。早该想到的。知道为什么我在启动 gorutines 之前输入ch1 &lt;- struct{}{} 不起作用吗?是因为 ch1 还没有激活还是什么?
  • 因为第一个 goroutine 开始等待从第三个 goroutine 接收,而这永远不会到来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 2015-09-13
相关资源
最近更新 更多