I've been recently reading a lot about parallelism and concurrency in Go, and I can't wrap my head around it. When I was reading this article about concurrency and parallelism in Go, I've came across this statement:
We can see that the goroutines are truly running in parallel. Both goroutines start running immediately and you can see them both competing for standard out to display their results.
This statement is related to this 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")
}
Which outputs:
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
So, does that means that in the runtime 2 cycles from the goroutines executing at the same time (so at this point we can call Go parallel language) or scheduler just switches context between those two threads (probably on fmt.Printf call) and executing only one cycle at one (concurrency, not true parallelism, as the author mentioned in the quote above)?
I'm confused.
In your case the function that prints a-z and 1-27 both start at the same time and you are waiting till both the go routines end. While having several go routines, your idea must be concurrent but if your hardware supports they might run parallel.
Also context switches are heavy so most of the times they are most probably not done. Go routines are really light and hundreds of them can be running at the same time.