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
Release: 2024-12-02 00:54:13
Original
622 people have browsed it

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)
}
Copy after login

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()
Copy after login

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!

source:php.cn
Statement of this Website
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
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template