在视频Google I/O 2012 - Go Concurrency Patterns中,Rob Pike在视频中大约17:00引入了复用模式。使用fanIn()函数,任何准备就绪的人都将首先交谈。
但是当我在here - play.golang.org/p/cvAi5MAAKT中汇编程序时,它总是按以下顺序运行
NumCPU: 4 //Edit#1 output
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
此代码有什么问题?
package main
import "fmt"
import "time"
import "math/rand"
//Pattern #2
//Multiplexing
func fanIn(in1, in2 <-chan string) <-chan string {
c := make(chan string)
go func() {for {c <- <-in1}}()
go func() {for {c <- <-in2}}()
return c
}
func boring(msg string) <-chan string {
c := make(chan string)
go func() {
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d\n", msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}()
return c
}
func main() {
//Edit#1 according to the first answer, add following two lines
fmt.Println("NumCPU: ", runtime.NumCPU())
runtime.GOMAXPROCS(runtime.NumCPU())
c := fanIn(boring("Joe"), boring("Ann"))
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
fmt.Println("You're both boring: I'm leaving")
}
Update1:
根据答案,我更改了代码,但结果仍然相同。我正在使用Windows7。请参见“编辑#1”中的上述更改。
Update2:
我找到了答案:只需将循环号增加到一个更大的数字(例如40),即使GOMAXPROCS使用默认值,它也会显示不同的顺序。您可以在操场上尝试。
最佳答案
没错,您只是没有告诉Go运行时使用多个线程。设置GOMAXPROCS环境变量*,或使用runtime
包的runtime.GOMAXPROCS函数。 GOMAXPROCS确定Go运行时创建的操作系统线程的数量,以多路复用您创建的goroutine。如果GOMAXPROCS为1(默认值),您通常会看到非常确定的外观行为。
例如,在运行程序时:
GOMAXPROCS=4 ./myProgram
例如在您的程序中:
runtime.GOMAXPROCS(runtime.NumCPU())
附言*如果您使用的是游乐场而不是您自己的机器,GOMAXPROCS将始终为1。