我正在学习Go中的并发模式,不确定Point A的目的是什么?
代码取自:https://talks.golang.org/2012/concurrency.slide#30
任何人都可以向我解释一下吗?感谢
type Message struct {
str string
wait chan bool
}
func main() {
c := fanIn(boring("Joe"), boring("Ann"))
for i := 0; i < 5; i++ {
msg1 := <-c
fmt.Println(msg1.str)
msg2 := <-c
fmt.Println(msg2.str)
msg1.wait <- true
msg2.wait <- true
}
fmt.Println("You're both boring; I'm leaving.")
}
func fanIn(input1, input2 <-chan Message) <-chan Message {
c := make(chan Message)
go func() {
for {
c <- <-input1
}
}()
go func() {
for {
c <- <-input2
}
}()
return c
}
func boring(msg string) <-chan Message {
waitForIt := make(chan bool)
c := make(chan Message)
go func() { // We launch the goroutine from inside the function.
for i := 0; ; i++ {
c <- Message{fmt.Sprintf("%s %d", msg, i), waitForIt}
time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond)
<-waitForIt // <-----------------Point A
}
}()
return c // Return the channel to the caller.
}
答案 0 :(得分:2)
fanIn
产生两个goroutines,从第一个和第二个&#34;无聊&#34;消息信道。由于两个goroutine都可能正在运行(另一个正在运行或正在运行),我们不知道元素被写入统一通道的顺序:
A A A A A \
> A B B A A A B A B B
B B B B B /
请注意,生成的序列没有特定的顺序。
这可以通过commenting out the "waiting"-channels来证明:
Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Joe 4
Joe 5
Ann 3
You're both boring; I'm leaving.
等待通道存在以恢复序列,因为您链接的幻灯片说。我们想要这个:
A A A A A \
> A B A B A B A B A B
B B B B B /
请注意Ann和Joe talk one after the other now:
Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Ann 3
Joe 4
Ann 4
You're both boring; I'm leaving.
这段代码的作者决定通过让他们等待waitForIt
并在main
中通知来同步写入通道。此行为依赖于我们在main
&#39; s for
中获得的前两条消息 - 循环有序。如果不是,我们就会得到相反的序列。
也许我没有看到任何更多的绝对同步保证,也许作者不关心序列的顺序,只要它是一个重复的序列,但这段代码不会让我感觉不到特别好的并发和同步示例。
答案 1 :(得分:1)
整个演示文稿可在YouTube找到。大约8分钟,它将更接近你的问题。 Rob Pike解释了一切,但(这也是tomwilde所说的)演示中的例子缩小到只让观众看到最重要的东西。后来在演讲中,&#34;无聊&#34;将被&#34;有趣的&#34;取代。这将使Rob更加清楚地尝试解释。
答案 2 :(得分:0)
由于wait
频道每次只能包含一个元素,因此PointA只是通过阻止goroutine来确保没有人会继续。然后他将卸载&#34;按顺序通道,允许例程继续