How to Gracefully Wait for Go Routines to Finish
In Go, concurrency is achieved through goroutines, which are lightweight threads that run concurrently with the main routine. To ensure that the program doesn't exit before all goroutines have completed their tasks, it's crucial to properly wait for them to finish.
Using a Channel to Signal Completion
One common approach to waiting for goroutines is to use a boolean channel. When a goroutine completes its task, it sends a true value to the channel, and the main routine waits for that value by receiving from the channel.
func do_stuff(done chan bool) { fmt.Println("Doing stuff") done <- true } func main() { fmt.Println("Main") done := make(chan bool) go do_stuff(done) <-done }
Why does <-done work?
<-done is a blocking receive operation. This means that the main routine will wait until a value is sent to the done channel. Since the do_stuff goroutine explicitly sends a true value to the channel when it's finished, the main routine will receive it and continue execution.
What happens if we uncomment the last line?
If we uncomment the last line, we get a deadlock error because the channel is empty and no other goroutine is sending values to it. Therefore, the main routine will wait infinitely for a value to receive, resulting in a deadlock.
Alternative Approach Using Sync Package
For more complex concurrency scenarios, the sync package provides convenient synchronization mechanisms. For instance, if you need to parallelize a series of long-running functions, the following code snippet demonstrates how to use the sync.WaitGroup type:
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { longOp() wg.Done() }() } // will wait until wg.Done is called 10 times // since we made wg.Add(1) call 10 times wg.Wait() } func longOp() { time.Sleep(time.Second * 2) fmt.Println("long op done") }
In this example, the WaitGroup ensures that the main routine doesn't exit until all goroutines have called wg.Done.
The above is the detailed content of How to Gracefully Wait for Go Routines to Finish?. For more information, please follow other related articles on the PHP Chinese website!