注意:在这个问题中,我比较了两个版本的代码,并试图了解它们产生不同输出的原因。play.golang.org上两个版本的运行示例的链接是FIG1和FIG2。
我正在研究 Rob Pike 在 Google I/O 2012 上展示的Go Concurrency Patterns幻灯片,关于 Sequencing 的示例有点令人困惑。在幻灯片 29上,有一个如何在多路复用后恢复测序的示例。简而言之,来自多个通道的消息被多路复用到一个通道中,并且每个消息结构共享一个称为“waitForIt”的通道。该通道旨在确保提供消息的服务(在引用的示例中为无聊的服务)和服务的客户端是按顺序排列的。我不明白为什么,为了对 ABABAB 进行排序,客户端必须通过 waitForIt 通道发送2 个等待:
图。1
for i := 0; i < 10; i++ {
msg1 := <-c
fmt.Printf("%s\n", msg1.str)
msg2 := <-c
fmt.Printf("%s\n", msg2.str)
msg1.wait <- true
msg2.wait <- true /* why is this second wait necessary? */
}
如果 Message 结构共享同一个通道,为什么需要两次等待?一个<-wait是否就足够了,即
图2
for i := 0; i < 10; i++ {
msg1 := <-c
fmt.Printf("%s\n", msg1.str)
msg2 := <-c
fmt.Printf("%s\n", msg2.str)
msg1.wait <- true
}
然而,当使用单个等待时,消息 1 在输出开始时重复两次,然后顺序 ABAB... 随之而来,因此输出是:
Message 1: Iteration 0
Message 2: Iteration 0
Message 1: Iteration 1 // Message 1 is repeated twice
Message 1: Iteration 2 // Here's the repetition
Message 2: Iteration 1
Message 1: Iteration 3
Message 2: Iteration 2
Message 1: Iteration 4
Message 2: Iteration 3
Message 1: Iteration 5
当有两个发送到等待变量时,如图1 所示,顺序是ABAB ... 从头开始:
Message 1: Iteration 0
Message 2: Iteration 0
Message 1: Iteration 1
Message 2: Iteration 1
Message 1: Iteration 2
Message 2: Iteration 2
Message 1: Iteration 3
Message 2: Iteration 3
Message 1: Iteration 4
Message 2: Iteration 4
为什么正确序列需要在同一通道上进行第二次发送等待?