Skip to content

Channel Synchronization, waitgroups

How can you ensure that the following program only exists after the go-routine has executed -

package main
func expensiveOp() {
sum := 0
for i := range 1000000 {
sum += i
}
println(sum)
}
func main() {
go expensiveOp()
println("main Function ended")
}

Solution - Add an unbuffered channel that blocks the receiver

package main
func expensiveOp(ch chan<- bool) {
sum := 0
for i := range 1000000 {
sum += i
}
println(sum)
ch <- true
}
func main() {
ch := make(chan bool)
go expensiveOp(ch)
<-ch
println("main Function ended")
}

Waitgroups

In Go, a WaitGroup is a synchronization primitive that allows you to wait for a collection of goroutines to finish executing.

Write a program that runs 5 different go routines and waits for all of them to exit before printing “done”

Ugly approach (without waitgroups)

package main
func expensiveOp(ch chan<- bool) {
sum := 0
for i := range 1000000 {
sum += i
}
println(sum)
ch <- true
}
func main() {
ch1 := make(chan bool)
go expensiveOp(ch1)
ch2 := make(chan bool)
go expensiveOp(ch2)
ch3 := make(chan bool)
go expensiveOp(ch3)
ch4 := make(chan bool)
go expensiveOp(ch4)
ch5 := make(chan bool)
go expensiveOp(ch5)
<-ch1
<-ch2
<-ch3
<-ch4
<-ch5
println("main Function ended")
}

Better approach (Using waitgroups)

package main
import "sync"
func expensiveOp() {
sum := 0
for i := range 1000000 {
sum += i
}
println(sum)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
expensiveOp()
}()
}
wg.Wait()
println("main Function ended")
}

Assignment

Add a timeout to a go-routine so it gets ignored and execution continues if it takes more than 10 seconds