Home >Backend Development >Golang >How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

Susan Sarandon
Susan SarandonOriginal
2024-12-02 00:54:13562browse

How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?

Waiting for Buffered Channel Emptiness Using a WaitGroup

In concurrent programming, it's often necessary to control the number of concurrently executing goroutines. A common approach is to use a buffered channel as a semaphore. However, it's important to note the limitations of this approach.

Consider the following example:

ints := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 sem := make(chan struct{}, 2)
for _, i := range ints {
  sem<- struct{}{}
  go func(id int, sem chan struct{}) {
    // do something
    <-sem
  }(i, sem)
}

This code uses a buffered channel (sem) of size 2 to limit the number of concurrent goroutines to 2. However, there's a problem: the program may end before the last few goroutines have completed their tasks. This is because the buffered channel can become empty at any point during processing, even while the program is dispatching more goroutines.

To wait for a buffered channel to drain, we cannot rely on the channel itself. Instead, we can use a sync.WaitGroup to track the number of outstanding goroutines:

sem := make(chan struct{}, 2)
var wg sync.WaitGroup
for _, i := range ints {
  wg.Add(1)
  sem<- struct{}{}
  go func(id int) {
    defer wg.Done()
    // do something
    <-sem
  }(i)
}
wg.Wait()

In this modified code, we use wg.Add(1) to increment the wait group before dispatching each goroutine. The defer wg.Done() statement then decrements the wait group when the goroutine completes its task. Finally, wg.Wait() blocks until the wait group reaches zero, ensuring that all goroutines have finished executing. This approach allows us to wait for the channel to drain and ensures that the program doesn't terminate prematurely.

The above is the detailed content of How Can I Ensure All Goroutines Finish When Using a Buffered Channel as a Semaphore?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn