Go并发模式 – 模式 #2

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

Go Concurrency Patterns - Pattern #2

问题

在视频Google I/O 2012 - Go Concurrency Patterns中,Rob Pike在视频的大约17:00处介绍了多路复用模式。使用fanIn()函数,谁先准备好就会先说话。

但是当我在这里 - play.golang.org/p/cvAi5MAAKT中组装程序时,它总是按顺序运行,如下所示:

  1. NumCPU: 4 //Edit#1 output
  2. Joe 0
  3. Ann 0
  4. Joe 1
  5. Ann 1
  6. Joe 2
  7. Ann 2
  8. Joe 3
  9. Ann 3
  10. Joe 4
  11. Ann 4
  12. You're both boring: I'm leaving

这段代码有什么问题?

  1. package main
  2. import "fmt"
  3. import "time"
  4. import "math/rand"
  5. //Pattern #2
  6. //Multiplexing
  7. func fanIn(in1, in2 <-chan string) <-chan string {
  8. c := make(chan string)
  9. go func() {for {c <- <-in1}}()
  10. go func() {for {c <- <-in2}}()
  11. return c
  12. }
  13. func boring(msg string) <-chan string {
  14. c := make(chan string)
  15. go func() {
  16. for i := 0; ; i++ {
  17. c <- fmt.Sprintf("%s %d\n", msg, i)
  18. time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
  19. }
  20. }()
  21. return c
  22. }
  23. func main() {
  24. //Edit#1 according to the first answer, add following two lines
  25. fmt.Println("NumCPU: ", runtime.NumCPU())
  26. runtime.GOMAXPROCS(runtime.NumCPU())
  27. c := fanIn(boring("Joe"), boring("Ann"))
  28. for i := 0; i < 10; i++ {
  29. fmt.Println(<-c)
  30. }
  31. fmt.Println("You're both boring: I'm leaving")
  32. }

更新1:
根据答案,我已经更改了代码,但结果仍然相同。我正在使用Windows 7。请参见上面的“Edit#1”中的更改。

更新2:

我找到了答案:只需将循环次数增加到一个较大的数字(比如40),即使GOMAXPROCS使用默认值,它也会显示出不同的顺序。你可以在playground中尝试一下。

英文:

In the video Google I/O 2012 - Go Concurrency Patterns, Rob Pike introduced the Multiplexing Pattern at about 17:00 in the video. Using the fanIn() function, whoever is ready will talk first.

But when I assemble the program in here - play.golang.org/p/cvAi5MAAKT, it always run in sequence as

  1. NumCPU: 4 //Edit#1 output
  2. Joe 0
  3. Ann 0
  4. Joe 1
  5. Ann 1
  6. Joe 2
  7. Ann 2
  8. Joe 3
  9. Ann 3
  10. Joe 4
  11. Ann 4
  12. You&#39;re both boring: I&#39;m leaving

What's wrong with this code?

  1. package main
  2. import &quot;fmt&quot;
  3. import &quot;time&quot;
  4. import &quot;math/rand&quot;
  5. //Pattern #2
  6. //Multiplexing
  7. func fanIn(in1, in2 &lt;-chan string) &lt;-chan string {
  8. c := make(chan string)
  9. go func() {for {c &lt;- &lt;-in1}}()
  10. go func() {for {c &lt;- &lt;-in2}}()
  11. return c
  12. }
  13. func boring(msg string) &lt;-chan string {
  14. c := make(chan string)
  15. go func() {
  16. for i := 0; ; i++ {
  17. c &lt;- fmt.Sprintf(&quot;%s %d\n&quot;, msg, i)
  18. time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
  19. }
  20. }()
  21. return c
  22. }
  23. func main() {
  24. //Edit#1 according to the first answer, add following two lines
  25. fmt.Println(&quot;NumCPU: &quot;, runtime.NumCPU())
  26. runtime.GOMAXPROCS(runtime.NumCPU())
  27. c := fanIn(boring(&quot;Joe&quot;), boring(&quot;Ann&quot;))
  28. for i := 0; i &lt; 10; i++ {
  29. fmt.Println(&lt;-c)
  30. }
  31. fmt.Println(&quot;You&#39;re both boring: I&#39;m leaving&quot;)
  32. }

Update1:
According to the answer, I've changed the code, but the result is still the same. I'm using windows 7. See the changes above in "Edit#1".

Update2:

I found the answer: Just increase the loop number to a larger number(say 40), it will show out the different orders even if the GOMAXPROCS use the default value. You can try it from the playground.

答案1

得分: 3

没问题,你只是还没有告诉Go运行时使用多个线程。设置GOMAXPROCS环境变量,或使用runtime包的runtime.GOMAXPROCS函数。GOMAXPROCS确定Go运行时创建的操作系统线程数,用于复用你创建的goroutine。如果GOMAXPROCS为1(默认值),你通常会看到非常确定性的行为。

例如,在运行程序时:

  1. GOMAXPROCS=4 ./myProgram

例如,在你的程序中:

  1. runtime.GOMAXPROCS(runtime.NumCPU())

P.S. *如果你使用的是Playground而不是自己的机器,GOMAXPROCS将始终为1。

英文:

Nothing is wrong, you just haven't told the Go runtime to use more than one thread. Set the GOMAXPROCS environment variable*, or use the runtime package's runtime.GOMAXPROCS function. GOMAXPROCS determines the number of OS threads the Go runtimes creates to multiplex goroutines that you create over. If GOMAXPROCS is 1 (the default), you will often see very deterministic looking behaviour.

For example when running your program:

  1. GOMAXPROCS=4 ./myProgram

For example in your program:

  1. runtime.GOMAXPROCS(runtime.NumCPU())

P.S. *If you are using the playground and not your own machine, GOMAXPROCS will always be 1.

huangapple
  • 本文由 发表于 2014年2月13日 00:55:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/21734402.html
匿名

发表评论

匿名网友

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

确定