Cancel All goroutines if Any One of Them is Done
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.