我有这样的示例代码,我正面临着这个同步问题,谁能帮帮我,我如何才能实现。
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
}
}
实际输出。
writing i 0
second channel
seconds stats 0
base stats 0
writing i 1
writing i 2
seconds stats 1
seconds stats 2
我想要的输出是这样的:
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
你 可以 编写goroutine,让它们互相等待。 例如,这里有一个中级的运输机函数,它位于生产者和消费者之间,迫使他们蹒跚前行。
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
}
}
但这是,一句话,愚蠢的。 强迫生产者等待,直到消费者完成任务,这是没有意义的 和 使用通道,因为如果我们想让生产者等待,我们只需要写。
for ... {
produced_value = producerStep()
final(middle(produced_value))
}
其中 producerStep()
产生下一个价值,就完全不考虑渠道了。
还是。这里是围棋赛场上完整的步法程序。.
代码按照预期工作。但有一点你可以做,在连续的两步之间加一定的间隔。runLoop()
函数。但把一个固定的区间是 不建议,你需要写一些代码来确保这些工作的完成。只是展示这个例子,告诉你这里发生了什么。
func runLoop(second chan int) {
for i := 0; i < 5; i++ {
fmt.Println("writing i", i)
second <- i
time.Sleep(100 * time.Millisecond) // <-- here
}
}
这里发生了什么?只是给足够的时间来完成那些在不同的goroutine中运行的工作。
输出。
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
writing i 3
seconds stats 3
base stats 3
writing i 4
seconds stats 4
base stats 4