Home >Backend Development >Golang >How to Ensure Go Routines Complete Before Main Exits?
Waiting for Go Routine Completion
In Go, a common practice is to use goroutines to perform concurrent tasks. To ensure that the main program waits for all goroutines to finish before exiting, it's crucial to implement proper synchronization mechanisms.
One approach, as mentioned in the question, involves using a boolean channel (done):
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 <-done Works:
The operation <-done is a blocking channel receive. It waits until a value is sent on the channel done. In the provided code, do_stuff sends true on the channel upon task completion, causing the <-done operation in main to succeed.
Deadlock from Uncommenting the Last Line:
Uncommenting the last line in main leads to a deadlock:
func main() { fmt.Println("Main") done := make(chan bool) go do_stuff(done) <-done // <-done }
This second <-done operation attempts to read from an empty channel without any goroutine sending values to it. As a result, the program hangs in a deadlock.
Alternative Synchronization Method Using the sync Package:
For more complex scenarios, the sync package offers alternative synchronization primitives. In the provided code, sync.WaitGroup can effectively keep track of goroutine completion:
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 (10 goroutines finish) wg.Wait() } func longOp() { time.Sleep(time.Second * 2) fmt.Println("long op done") }
The use of sync.WaitGroup ensures that main waits for all 10 goroutines to complete before exiting the program.
The above is the detailed content of How to Ensure Go Routines Complete Before Main Exits?. For more information, please follow other related articles on the PHP Chinese website!