Go

Concurrency Limit via Buffered Channel (Semaphore)

admin by @admin ADMIN
1h ago
May 31, 2026
Public
0 0 up · 0 down Sign in to vote
A buffered channel of size N is the simplest semaphore in Go — acquire by sending, release by receiving. Zero dependencies, no sync.Semaphore needed.
Go
Raw
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
}
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.