我有这个示例代码,我正面临这个同步问题,任何人都可以帮助我如何实现这一点。
package main
import "fmt"
func main() {
baseChan := make(chan int)
go func(bCh chan int){
for {
select{
case stats, _ := <- bCh:
fmt.Println("base stats", stats)
}}
}(baseChan)
second := make(chan int)
go func (sCh chan int) {
fmt.Println("second channel")
for {
select {
case stats, _ := <- sCh:
fmt.Println("seconds stats", stats)
baseChan <- stats
}
}
}(second)
runLoop(second)
}
func runLoop(second chan int) {
for i := 0; i < 5; i++ {
fmt.Println("writing i", i)
second <- i
}
}
Run Code Online (Sandbox Code Playgroud)
实际输出:
writing i 0
second channel
seconds stats 0
base stats 0
writing i 1
writing i 2
seconds stats 1
seconds stats 2
Run Code Online (Sandbox Code Playgroud)
我希望输出是这样的,
writing i 0
seconds stats 0
base stats 0
writing i 1
seconds stats 1
base stats 1
writing i 2
seconds stats 2
base stats 2
Run Code Online (Sandbox Code Playgroud)
您可以编写 goroutines 以便它们相互等待。例如,这是一个位于生产者和消费者之间的中级传输器功能,并迫使他们继续前进:
func middle(in, out chan int, inAck, outAck chan struct{}) {
defer close(out)
for value := range in {
fmt.Println("middle got", value)
out <- value // send
fmt.Println("middle now waiting for ack from final")
<-outAck // wait for our consumer
inAck <- struct{}{} // allow our producer to continue
}
}
Run Code Online (Sandbox Code Playgroud)
但总之,这是愚蠢的。强制生产者等待消费者完成并使用通道是没有意义的,因为如果我们想让生产者等待,我们只需写:
for ... {
produced_value = producerStep()
final(middle(produced_value))
}
Run Code Online (Sandbox Code Playgroud)
whereproducerStep()产生下一个值,并且完全省去通道。