1
votes

I have the following example below where two goroutine should be running in parallel. But if you check the output, the second goroutine only runs after the first goroutine completes. So, it's sequential.

Adding 2 processors: runtime.GOMAXPROCS(2) also didn't help. I'm running on a Mac pro with 8 cores and it is definitely not a hardware issue. So my question - Is Golang really parallel and how to make example below run in parallel?

Output:

Thread 1
Thread 1
  …………....
Thread 1
Thread 1
Thread 2
Thread 2
  …………....
Thread 2
Thread 2

Go code:

package main

import (
    "runtime"
    "time"
)

func main() {

    runtime.GOMAXPROCS(2)

    go func() {
        for i := 0; i < 100; i++ {
            println("Thread 1")
            //time.Sleep(time.Millisecond * 10)
        }
    }()

    go func() {
        for i := 0; i < 100; i++ {
            println("Thread 2")
            //time.Sleep(time.Millisecond * 10)
        }
    }()

    time.Sleep(time.Second)
}
1
"So, it's sequential." No it is not. What's your question?Volker
If you want to see the goroutines running in parallel, you may try to use runtime.LockOSThread(). Playground. But it doesn't guarantee that those threads are running on different cpu's. Maybe you can get ideas here: stackoverflow.com/a/19759235/694331ANisus
@Volker: Why it not sequential ? It's clearly show ever if we have 2 process Go runtime does not separate each goroutine to individual process/thread. Question why ?PARUS
Goroutines are not run "in parallel" but concurrently. Formally you cannot force two parts of a Go program to execute at the same time. All you can do is: Make it possible for "parallel" (at the same time) execution. Or impossible. Tight or short loops which do not allow the scheduler to control execution are one example of code that prevents "parallel" execution. Read blog.golang.org/concurrency-is-not-parallelism.Volker

1 Answers

4
votes

In order to understand your program is running parallel or concurrently using goroutine is print the different value in sequence. From this article : Concurrency, Goroutines and GOMAXPROCS .

Your code can't express enough to represent a parallel call. Please see the code below.

package main

import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    runtime.GOMAXPROCS(2)

    var wg sync.WaitGroup
    wg.Add(2)

    fmt.Println("Starting Go Routines")
    go func() {
        defer wg.Done()

        //time.Sleep(1 * time.Microsecond)
        for char := 'a'; char < 'a'+26; char++ {
            fmt.Printf("%c ", char)
        }
    }()

    go func() {
        defer wg.Done()

        for number := 1; number < 27; number++ {
            fmt.Printf("%d ", number)
        }
    }()

    fmt.Println("Waiting To Finish")
    wg.Wait()

    fmt.Println("\nTerminating Program")
}

As you can see from the above code print the different value sequence using for loop.

The output would be different if you comment the runtime.GOMAXPROCS(2) and uncomment the line on time.Sleep(1 * time.Microsecond).