英文:
How can I overlap goroutines?
问题
我有三个goroutine,它们应该以某种循环方式工作。例如,我有以下代码:
go first() {
// 做一些事情
}
go second() {
// 做另一种事情
}
go third() {
// 做第三种事情
}
它们应该按照以下顺序工作:
First - second - third - first - /以此类推/。
我猜我需要使用通道来实现,但我无法找到正确的方法。如果我创建三个不同的通道
FirstToSecond,
SeocndToThird,
ThirdToFirst,然后运行程序时,我会得到错误:
fatal error: all goroutines are asleep - deadlock!
但是,如果我去掉ThirdToFirst,我就有一个正确的循环,然后goroutine开始随机工作。
我肯定漏掉了什么,但是是什么呢?
以下是带有两个goroutine的示例代码:
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()
}
英文:
I have three gorutines, which should work in some sort of loop. For example, I have
go first() {
// do some stuff
}
go second() {
// do another kind of stuff
}
go third() {
// do third kind of stuff
}
And they have to work like that:
First - second - third - first - /and so on and so on/
I guess I have to use channels fo that, but I can't figure out proper way to do so.
If I make three different channels
FirstToSecond,
SeocndToThird,
ThirdToFirst, then when I run a program, I get error:
fatal error: all goroutines are asleep - deadlock!
But if I get rid of ThirdToFirst, I have one proper loop, and then gorutines start to work randomly.
I'm certainly missing something, but what?
Example code with two gorutines
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()
}
答案1
得分: 1
如果您需要这样的顺序执行,您可能需要重新评估使用goroutine的需求。然而,您描述的解决方案是正确的:
go first() {
for {
<-ch1
// 做一些事情
ch2<-struct{}{}
}
}()
go second() {
for {
<-ch2
// 做一些事情
ch3<-struct{}{}
}
}()
go third() {
for {
<-ch3
// 做一些事情
ch1<-struct{}{}
}
}()
然而,这是一个循环设置,您必须在此结构之外启动第一个:
go first() {...}()
go second() {...}()
go third() {...}()
// 启动第一个
ch1<-struct{}{}
英文:
If you need such sequencing, you might reevaluate your need to use goroutines. However, the way you described the solution is correct:
go first() {
for {
<-ch1
// do stuff
ch2<-struct{}{}
}
}()
go second() {
for {
<-ch2
// do stuff
ch3<-struct{}{}
}
}()
go third() {
for {
<-ch3
// do stuff
ch1<-struct{}{}
}
}()
However, this is a circular setup, and you have to start the first one outside this structure:
go first() {...}()
go second() {...}()
go third() {...} ()
// Start the first one
ch1<-struct{}{}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论