Using WaitGroup in Golang

Go routines are a great selling point for golang, making it a choice of a lots of developers out there. In this post we will see a common problem with these goroutines and try to solve it.

Let’s see a simple code snippet illustrating this problem,

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import "fmt"
  
func runner1() {
    fmt.Print("\nI am first runner")
}
  
func runner2() {
    fmt.Print("\nI am second runner")
}
  
func execute() {
    go runner1()
    go runner2()
  
}
  
func main() {
    
    // Launching both the runners
    execute()
}

chevron_right


As you just saw there was nothing in the output, this because as soon as you launch both the goroutines, your main function just got terminated. And every program in Golang executes until main function is not terminated. So, what can we do with this problem

1. We can wait for some time after launching the runners, for this purpose we will use “time” packages function “Sleep” which pauses the execution of function for given duration,

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import (
    "fmt"
    "time"
)
  
func runner1() {
    fmt.Print("\nI am first runner")
}
  
func runner2() {
    fmt.Print("\nI am second runner")
}
  
func execute() {
    go runner1()
    go runner2()
  
}
  
func main() {
  
    // Launching both the runners
    execute()
    time.Sleep(time.Second)
}

chevron_right


 



Output:

I am second runner
I am first runner

We just solve the problem, after launching our runners we wait for a second, so our main function was sleeping(blocked) for 1 sec. In that duration all of the go routines were executed successfully. But Golang is a fast language, It doesn’t take 1 sec to just print 2 strings.

The problem is that, our executors executes in bit amount of time so we unnecessarily  blocking the program for 1 sec. In this example it doesn’t seems to be a critical problem but if you making a production grade server who is going to serve 1000’s of request concurrently this will be a big problem.

2. Let’s use another Golang’s standard library primitive “sync.WaitGroup“. WaitGroup is actually a type of counter which blocks the execution of function (or might say A goroutine) until its internal counter become 0.

How It Works ?

WaitGroup exports 3 methods.

1 Add(int)  It increases WaitGroup counter by given integer value.
2 Done()  It decreases WaitGroup counter by 1, we will use it to indicate termination of a goroutine.
3 Wait() It Blocks the execution until it’s internal counter becomes 0.

Note: WaitGroup is concurrency safe, so its safe to pass pointer to it as argument for Groutines.

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import (
    "fmt"
    "sync"
)
  
func runner1(wg *sync.WaitGroup) {
    defer wg.Done() // This decreases counter by 1
    fmt.Print("\nI am first runner")
  
}
  
func runner2(wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Print("\nI am second runner")
}
  
func execute() {
    wg := new(sync.WaitGroup)
    wg.Add(2)
  
    // We are increasing the counter by 2
    // because we have 2 goroutines
    go runner1(wg)
    go runner2(wg)
  
    // This Blocks the execution
    // until its counter become 0
    wg.Wait()
}
  
func main() {
    // Launching both the runners
    execute()
}

chevron_right


 

Output:

I am second runner
I am first runner

The output is same but we out program doesn’t block for 1 sec . Pattern, we showed you above is a common practice in writing concurrent code in Golang.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.