Waiting for a Buffered Channel to Drain
In the provided code, a buffered channel is used as a semaphore to limit the number of concurrently running goroutines. However, without an explicit mechanism to wait for the channel to drain, the main program may terminate before all goroutines have finished execution.
Problem:
How to ensure that the program waits for all goroutines to complete before exiting?
Answer:
Using a semaphore (channel) for this purpose is not ideal because there is no built-in way to check the channel's length and wait for it to reach 0. To properly wait for goroutines to finish, consider using a synchronization primitive like a sync.WaitGroup.
Updated Code:
sem := make(chan struct{}, 2) var wg sync.WaitGroup for _, i := range ints { wg.Add(1) // acquire semaphore sem <- struct{}{} // start long running go routine go func(id int) { defer wg.Done() // do something // release semaphore <-sem }(i) } wg.Wait()
The sync.WaitGroup maintains a count of outstanding tasks (goroutines in this case). This allows the main program to wait until all tasks have completed. The wg.Add(1) increments the task count before starting a new goroutine, and wg.Done() decrements the count when a goroutine finishes. The wg.Wait() call blocks the main program until the task count reaches 0, ensuring that all goroutines have completed before the program exits.
The above is the detailed content of How to Ensure All Goroutines Complete Before Program Exit When Using a Buffered Channel as a Semaphore?. For more information, please follow other related articles on the PHP Chinese website!