Why? #
If you're looking at semaphores, there is a chance you've got some base concurrency going on and you're interested controlling access to a system across your multiple goroutines.
Maybe you've got 100 go routines and an api which can only handle 10 requests at a time.
The easy approach #
Fortunately in go, it's relatively easy to come up with a solution.
package main
import (
	"fmt"
	"sync"
)
func main() {
	const apiLimit = 5
	const numTasks = 10
	// Create a buffered channel to implement the semaphore
	semaphore := make(chan struct{}, apiLimit)
	// WaitGroup to wait for all goroutines to finish
	var wg sync.WaitGroup
	// Simulated task function
	task := func(i int) {
		defer wg.Done()
		// Acquire semaphore (block if the limit is reached)
		semaphore <- struct{}{}
		defer func() {
			// Release semaphore
			<-semaphore
		}()
		// do some work
	}
	// Start workers
	for i := 0; i < numTasks; i++ {
		wg.Add(1)
		go task(i)
	}
	// Wait for all workers to finish
	wg.Wait()
	fmt.Println("All tasks completed.")
}
          last updated: