A simple and effective way to manage running lots of goroutines in your Go software.
ThreadQueue provides a thread Queue implementation for Go that limits the number of concurrently running goroutines. This helps prevent resource exhaustion when dealing with a large number of concurrent tasks.
go get github.com/wltechblog/threadqueuepackage main
import (
"fmt"
"sync"
"time"
"github.com/wltechblog/threadqueue"
)
func main() {
// Create a new thread Queue with a maximum of 5 concurrent goroutines
Queue := threadqueue.New(5)
var wg sync.WaitGroup
// Launch 20 goroutines, but only 5 will run at a time
for i := 0; i < 20; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
// Join the Queue (blocks until a slot is available)
Queue.Join()
defer Queue.Leave()
// Do some work
fmt.Printf("Worker %d is running\n", id)
time.Sleep(100 * time.Millisecond)
fmt.Printf("Worker %d is done\n", id)
}(i)
}
wg.Wait()
}- Always call
Leave()afterJoin(), preferably usingdefer:
Queue.Join()
defer Queue.Leave()- Use a wait group to ensure all goroutines complete before your program exits:
var wg sync.WaitGroup
wg.Add(numTasks)
for i := 0; i < numTasks; i++ {
go func() {
defer wg.Done()
Queue.Join()
defer Queue.Leave()
// Do work
}()
}
wg.Wait()- Choose an appropriate Queue size based on your system resources and the nature of your tasks:
- CPU-bound tasks: typically use
runtime.NumCPU()or slightly higher - I/O-bound tasks: can use a higher number as these tasks spend time waiting
- CPU-bound tasks: typically use
Creates a new thread Queue with the specified maximum number of concurrent goroutines.
Queue := threadqueue.New(10) // Create a Queue with max 10 concurrent goroutinesBlocks until the calling goroutine can enter the thread Queue. If the Queue is at capacity, the goroutine will wait until another goroutine leaves.
Queue.Join() // Wait until we can enter the QueueNotifies the Queue that the calling goroutine has completed its work and is exiting the Queue. This frees up a slot for another waiting goroutine.
Queue.Leave() // Signal that we're done with the QueueProvided under the GPL2.0 license.