【发布时间】:2013-05-28 23:20:53
【问题描述】:
注意:在这个问题中,我比较了两个版本的代码,并试图了解它们产生不同输出的原因。 play.golang.org 上两个版本的运行示例的链接是 FIG1 和 FIG2。
我正在研究 Rob Pike 在 2012 年 Google I/O 上展示的 Go Concurrency Patterns 幻灯片,而关于 Sequencing 的示例有点令人困惑。在Slide 29 上有一个示例,说明如何在多路复用 之后恢复排序。简而言之,来自多个通道的消息被多路复用到一个通道中,并且每个消息结构共享一个称为“waitForIt”的通道。此通道旨在确保提供消息的服务(在引用的示例中为 boring 服务)和服务的客户端是按顺序排列的。我不明白为什么,为了获得 A-B-A-B-A-B 的序列,客户端必须通过 waitForIt 通道发送 2 等待:
FIG1
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 结构共享同一个通道,为什么需要两次等待?一个 是否就足够了,即
FIG2
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 在输出开始时重复两次,然后顺序 A-B-A-B... 随之而来,因此输出是:
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
当有两次发送到wait变量时,如FIG1,顺序是A-B-A-B...从头开始:
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
为什么第二次发送到 wait 需要一个正确的序列?
【问题讨论】: