注意:在这个问题中,我比较了两个版本的代码,并尝试理解它们产生不同输出的原因。在 play.golang.org 上运行两个版本示例的链接是FIG1和FIG2。
我正在处理Rob Pike在Google I / O 2012上提供的Go Concurrency Patterns幻灯片,有关排序的示例有点令人困惑。在Slide 29上有一个示例,说明如何在多路复用之后恢复排序。简而言之,来自多个通道的消息被多路复用到单个通道中,并且每个消息结构共享一个名为“waitForIt”的通道。此通道旨在确保提供消息的服务(在引用的示例中为无聊的服务)和服务的客户端按顺序进行。我不明白为什么,为了对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结构共享同一个通道,为什么需要两次等待?不应该只有一个&lt; -wait 就足够了,即
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
如果等待变量中有两个发送,如 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
为什么第二个发送到等待在正确序列所需的同一个通道上?
答案 0 :(得分:2)
阅读正确的例子[1]我猜你已经知道为什么你需要两个“等待它”。
以防万一:
您从频道中读取了两条消息。 每个消息生成器(无聊的goroutine)都在等待“等待它”。 所以你需要发送两个“等待它”,否则其中一个将继续等待。
如果您只通过频道发送一个“真实”,那么Joe会收到“等待它”,并且可以发送新消息,但Ann会一直等待(或反转)。
我想在这一点上你的程序将陷入僵局。您想要阅读两条消息,但只能接收一条消息(来自Joe)。
我没有测试过,但我想是的。如果我错了,请告诉我。
[1] http://talks.golang.org/2012/concurrency/support/sequenceboring.go
答案 1 :(得分:0)
上面的测序示例不正确。可以找到正确的示例here。