I am new to Golang and trying to understand Concurrency and Parallel. I read below mentioned article about Concurrency and Parallel. I have executed same program. But not getting the same ( mixed letter & character ) output. Getting first all letters then characters. it seems like concurrency is working not Parallel is not.
Article says add runtime.GOMAXPROCS(4) to make parallel.
Why I am not getting parallel out ?
I am using 4 core CPU system and GO version 1.8.2
https://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html
I know that if we add Sleep then i can see parallel output, as per Concurrency concept . But Parallelism says if system has more than one CPU, then each thread will run in one CPU and it becomes Parallel process. My question here is Why I am not getting parallel output though my system has 4 core and added runtime.GOMAXPROCS(4), .
Go Program
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()
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("
Terminating Program")
}
My Output
Starting Go Routines
Waiting To Finish
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 a
b c d e f g h i j k l m n o p q r s t u v w x y z
Terminating Program
Expected Output ( not the same , But Parallel output )
Starting Go Routines
Waiting To Finish
a b 1 2 3 4 c d e f 5 g h 6 i 7 j 8 k 9 10 11 12 l m n o p q 13 r s 14
t 15 u v 16 w 17 x y 18 z 19 20 21 22 23 24 25 26
Terminating Program
Since for loop has condition 27 in my above example, program execution was fast and not able to see parallelism. I have written different example and increased the condition then I could see the Parallel output.
package main
import (
"fmt"
"runtime"
"sync"
)
var wg sync.WaitGroup
func init() {
fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!", runtime.NumCPU())
}
func main() {
fmt.Println(" Welcome to concurrency")
wg.Add(2)
go one()
go two()
fmt.Println("Waiting To Finish")
wg.Wait()
fmt.Println("
Terminating Program")
}
func one() {
for i := 0; i < 200; i++ {
fmt.Println("one", i)
}
defer wg.Done()
}
func two() {
for i := 0; i < 200; i++ {
fmt.Println("Two:", i)
}
defer wg.Done()
}
UPDATE 8/28/2015: Go 1.5 is set to make the default value of GOMAXPROCS the same as the number of CPUs on your machine. I have removed the runtime.GOMAXPROCS(4)
In my opinion there are two troubles can be in this code. First idea:
runtime.GOMAXPROCS(2)
Using this row you allow only two workers, but you starting three Go Routines (Main takes one).
But the main problem that Go Routines finished too fast. Adding
time.Sleep(100000)
will solve this problem. package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
runtime.GOMAXPROCS(3)
var wg sync.WaitGroup
wg.Add(2)
fmt.Println("Starting Go Routines")
go func() {
defer wg.Done()
for char := 'a'; char < 'a'+26; char++ {
for i := 0; i < 10000; i++ {
_ = i * 2
}
fmt.Printf("%c ", char)
}
}()
go func() {
defer wg.Done()
for number := 1; number < 27; number++ {
for i := 0; i < 10000; i++ {
_ = i * 2
}
fmt.Printf("%d ", number)
}
}()
fmt.Println("Waiting To Finish")
wg.Wait()
fmt.Println("
Terminating Program")
}
In this case I've tried not to use sleep function, because they change thread status in scheduler. And I have this as a result.
Starting Go Routines
Waiting To Finish
1 2 3 4 a 5 b 6 c d 7 8 e f 9 g h 10 i j 11 k 12 l m 13 n 14 o p q 15 r 16 s 17 t u 18 v 19 w 20 x y 21 z 22 23 24 25 26
Terminating Program
That's because your algorithm doesn't do operations enough to allow to see parallelism. Try to raise the number of loops for the for statements, for example.