英文:
Go Concurrency Patterns - Pattern #2
问题
在视频Google I/O 2012 - Go Concurrency Patterns中,Rob Pike在视频的大约17:00处介绍了多路复用模式。使用fanIn()函数,谁先准备好就会先说话。
但是当我在这里 - 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")
}
更新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
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
What's wrong with this code?
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:
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(默认值),你通常会看到非常确定性的行为。
例如,在运行程序时:
GOMAXPROCS=4 ./myProgram
例如,在你的程序中:
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:
GOMAXPROCS=4 ./myProgram
For example in your program:
runtime.GOMAXPROCS(runtime.NumCPU())
P.S. *If you are using the playground and not your own machine, GOMAXPROCS will always be 1.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论