Golang : Concurrency and goroutine example




Golang has concurrency build into the core design and this is one of the main features that attracted many veteran developers(of course new comers as well) to learn Golang. While it is easy to comprehend how to use Goroutine, it can be difficult to implement sometimes.

We will explore some goroutine examples to learn how to implement concurrency into your program and how to mitigate some of the implementation issue.

Example 1:

 package main

 import (
 "fmt"
 )

 func echo(s string) {
 for i := 0; i < 5; i++ {
 fmt.Println(s)
 }
 }


 func main() {
 echo("good") // current

 go echo("bye") // spawn a new thread 

 var input string
 fmt.Scanln(&input) // pause to wait for go echo("bye") to complete
 }

execute this example 1 codes and see how it goes. Now, just for fun, remove these two lines :

 var input string
 fmt.Scanln(&input) // pause to wait for go echo("bye") to complete

and you will see that the output will only be lines like these

good

good

good

good

good

so what happened ? because without the fmt.Scanln() function to momentarily pause the program, the go echo("bye") thread did not have the time and free thread to execute before termination. That is... that the goroutines are scheduled for execution in single OS thread. To fix this issue, we need to allow the program to execute the go routines concurrently( switching between the scheduled routines ). We will use the runtime.Gosched() to do that.

Example 2:

 package main

 import (
 "fmt"
 "runtime"
 )

 func echo(s string) {
 for i := 0; i < 5; i++ {
 // runtime.Gosched() means let the CPU execute other goroutines thread and then come back.
 runtime.Gosched() // see http://golang.org/pkg/runtime/#Gosched
 fmt.Println(s)
 }
 }

 func main() {

 go echo("bye") // schedule this execution on a new thread
 // but do it before the first thread


 echo("good") // current [first thread]

 }

Output :

good

bye

good

bye

good

bye

good

bye

good

In case you are looking to maximize performance and take advantage of all the available CPU cores to process. You can add this line

 runtime.GOMAXPROCS(runtime.NumCPU())

Example 3 :

 package main

 import (
 "fmt"
 "runtime"
 )

 func echo(s string) {
 for i := 0; i < 5; i++ {
 runtime.Gosched() // see http://golang.org/pkg/runtime/#Gosched
 fmt.Println(s)
 }
 }

 func main() {

 // maximize CPU usage for multi threading
 runtime.GOMAXPROCS(runtime.NumCPU())

 go echo("bye") // schedule this execution on a new thread [second]

 go echo("world") // [third]

 echo("good") // current [first thread]

 }

Output :

good

bye

world

good

bye

world

good

bye

world

good

bye

world

good

Hope this tutorial can help you to understand more about Golang's concurrency and goroutines.

Oh... one last note, do not confuse concurrency with parallel programming.

"In programming, concurrency is the composition of independently executing processes, while parallelism is the simultaneous execution of (possibly related) computations. Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once."

See http://blog.golang.org/concurrency-is-not-parallelism

References :

http://golang.org/pkg/runtime/#Gosched

http://blog.golang.org/pipelines

  See also : Golang : Channels and buffered channels examples





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement