// Created on savesnippets.com ยท https://savesnippets.com/Bc6BcmZ3l8Vn1w package main import ( "fmt" "sync" "time" ) const concurrency = 3 var sem = make(chan struct{}, concurrency) // capacity = max in flight func work(id int, wg *sync.WaitGroup) { defer wg.Done() sem <- struct{}{} // acquire (blocks if full) defer func() { <-sem }() // release on exit fmt.Printf("[%d] start\n", id) time.Sleep(500 * time.Millisecond) fmt.Printf("[%d] done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 10; i++ { wg.Add(1) go work(i, &wg) } wg.Wait() // Observe: only 3 goroutines run concurrently at any time }