为什么这个Google I/O 2012并发示例不按预期工作?

huangapple go评论68阅读模式
英文:

Why is this Google I/O 2012 concurrency example not working as expected?

问题

我正在尝试跟随Rob Pike在Google I/O 2012的演讲“Go Concurrency”。我正在尝试一个例子,其中通道被多路复用,所以“Ann”和“Joe”不会同时交谈。但是使用下面的代码,他们仍然是同时进行的。我错在哪里了?

这是输出结果(在Ubuntu 10.04 LTS上的go版本go1.0.2):

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...

我错在哪里?谢谢!

英文:

I'm trying to follow along with Rob Pike's Google I/O 2012 talk called "Go Concurrency". I'm trying the example where channels are multiplexed so "Ann" and "Joe" don't talk in lock-step. But using the code below, they still are lock-stepping. Where am I going wrong?

Video: http://www.youtube.com/watch?v=f6kdp27TYZs&feature=player_detailpage#t=1025s

package main

import (
	"fmt"
	"time"
	"math/rand"
	)

func fanIn(input1, input2 <-chan string) <-chan string {
	c := make(chan string)
	go func() { for {c <- <-input1 } }()
	go func() { for {c <- <-input2 } }()
	return c
}

func main() {
	c := fanIn(boring("Joe"), boring("Ann"))
	for i:=0; i<10; i++ {
		fmt.Println(<-c)
	}
	fmt.Printf("You're both boring, I'm leaving...\n")
}

func boring(msg string) <-chan string {
	c := make(chan string)
	go func() { // launch goroutine from inside the fn
		for i:=0; ; i++ {
			c <- fmt.Sprintf("%s %d", msg, i)
			time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond )
		}
	}()
	return c
}

And the output of this (go version go1.0.2 on Ubuntu 10.04 LTS)

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...

Where did I go wrong? Thanks!

答案1

得分: 7

你的代码没问题,只是需要多次循环才能使它们不同步。只需要增加循环次数,你就会看到它们不再同步:

for i := 0; i < 20; i++ { // 循环20次通常足够看到不同步
    fmt.Println(<-c)
}

我得到了以下输出:

Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Ann 3
Joe 4
Ann 4
Joe 5
Ann 5
Joe 6
Ann 6
Ann 7
Joe 7
Joe 8
Joe 9
Ann 8
Ann 9
英文:

Your code is fine; it just tends to take a little more than that to get them out of sync. Just loop more times and you should see them get out of lock-step:

for i := 0; i &lt; 20; i++ { // Going up to 20 is enough to usually see it
    fmt.Println(&lt;-c)
}

I got this output:

<pre>
Joe 0
Ann 0
Joe 1
Ann 1
Joe 2
Ann 2
Joe 3
Ann 3
Joe 4
Ann 4
Joe 5
Ann 5
Joe 6
Ann 6
Ann 7
Joe 7
Joe 8
Joe 9
Ann 8
Ann 9
</pre>

huangapple
  • 本文由 发表于 2013年5月20日 03:32:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/16638628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定