In Go applications, coordinating the shutdown of multiple goroutines is crucial for ensuring their clean and synchronous termination. This article explores the issue of synchronizing two goroutines to return together upon the occurrence of an error in either routine.
Consider the following code snippet:
func main() { go func() { ... if err != nil { return } }() go func() { ... if err != nil { return } }() }
This scenario requires the synchronization of goroutines such that when one of them encounters an error and returns, the other should also terminate. The challenge lies in achieving this without introducing a write to a closed channel, which could result in a panic.
A highly effective solution involves utilizing Go's context package for communication between the goroutines. By creating a context and passing it to each goroutine, you can provide a mechanism for signaling their termination. Here's an updated code snippet demonstrating this approach:
package main import ( "context" "sync" ) func main() { ctx, cancel := context.WithCancel(context.Background()) wg := sync.WaitGroup{} wg.Add(3) go func() { defer wg.Done() for { select { // msg from other goroutine finish case <-ctx.Done(): // end } } }() go func() { defer wg.Done() for { select { // msg from other goroutine finish case <-ctx.Done(): // end } } }() go func() { defer wg.Done() // your operation // call cancel when this goroutine ends cancel() }() wg.Wait() }
In this code, the context variable ctx serves as the communication channel between the goroutines. When an error occurs in any of the goroutines, it calls cancel() on the context, which signals to the other goroutines to terminate. This elegant solution ensures the graceful shutdown of all goroutines without the risk of a panic.
The above is the detailed content of How to Gracefully Shutdown Multiple Goroutines in Go When an Error Occurs?. For more information, please follow other related articles on the PHP Chinese website!