package main import ( "fmt" "sync" "time" ) const maxConcurrent = 3 // Limit to 3 concurrent operations // simulate an operation that needs to be limited func limitedOperation(id int) { fmt.Printf("Worker %d: Starting operation... ", id) time.Sleep(time.Duration(2+id) * 200 * time.Millisecond) // Simulate work fmt.Printf("Worker %d: Operation finished. ", id) } func main() { semaphore := make(chan struct{}, maxConcurrent) // Buffered channel acts as a semaphore var wg sync.WaitGroup numWorkers := 10 fmt.Println("Starting workers, limited to", maxConcurrent, "concurrent operations.") for i := 1; i <= numWorkers; i++ { wg.Add(1) go func(workerID int) { defer wg.Done() semaphore <- struct{}{} // Acquire a slot (block if semaphore is full) fmt.Printf("Worker %d: Acquired slot. ", workerID) limitedOperation(workerID) <-semaphore // Release the slot fmt.Printf("Worker %d: Released slot. ", workerID) }(i) } wg.Wait() fmt.Println("All workers finished.") }