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