2
votes

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

1 Answers

3
votes

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.