Cancel All goroutines if Any One of Them is Done

April 4, 2021

In golang, concurrency is implemented with goroutine and we use channels to control them.

Often in concurrency programming, you will have a group of goroutines and want to terminate all of them if any one of them stops.

For example, you have a goroutine that read from a source and another goroutine write the result to output. If either the reader or the writer is done, you want to terminate the other.

The pattern you can use is to share a context among all the goroutines and use a done channel to check if any of them is done.

ctx, cancel := context.WithCancel(context.Background())
doneChan := make(chan struct{}, 2)
go writer(ctx, doneChan)
go reader(ctx, doneChan)
// stop all if any one is done
<-doneChan
cancel()

Here is how it works:

You create a shared context ctx with cancel and a done channel doneChan, both will be shared by all the goroutines. Each goroutine will stop if ctx is canceled. You start all the goroutines, and wait on the doneChan. If anything is readable from the done channel, that means one of the goroutines is done. Then you call the cancel function to cancel all the goroutines.

golang concurrency