3

注意:在这个问题中,我比较了两个版本的代码,并试图了解它们产生不同输出的原因。play.golang.org上两个版本的运行示例的链接是FIG1FIG2


我正在研究 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

为什么正确序列需要在同一通道上进行第二次发送等待?

4

2 回答 2

2

阅读正确的示例 [1] 我想您可能已经知道为什么您需要两者“等待它”。

以防万一:

您从频道中读取了两条消息。每个消息生成器(无聊中的 goroutine)都在等待“等待它”。所以你需要发送两个“等待它”,否则其中一个会一直等待。

如果您通过通道只发送一个“真”,那么乔会收到它的“等待它”并可以发送一条新消息,但安一直在等待(或反转)。

我想此时您的程序将陷入僵局。您想阅读两条消息,但您只能收到一条(来自 Joe)。

我没有测试过,但我认为是这样。让我知道我是否错了。

[1] http://talks.golang.org/2012/concurrency/support/sequenceboring.go

于 2013-06-03T07:29:01.880 回答
0

上面的排序示例不正确。正确的例子可以在这里找到。

于 2013-06-02T19:42:50.783 回答