Sobes.tech
Senior

You have a service that spawns many goroutines. How would you limit the number of concurrently running goroutines?

sobes.tech AI

Answer from AI

To limit the number of concurrently running goroutines in Go, semaphores or buffered channels are often used. The idea is to create a channel with a capacity equal to the maximum number of parallel goroutines, and before starting a goroutine, send a value into this channel, and after it finishes, remove it, freeing space for the next one.

Example:

package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, sem chan struct{}, wg *sync.WaitGroup) {
    defer wg.Done()
    sem <- struct{}{}          // acquire a slot
    defer func() { <-sem }()   // release the slot after work

    fmt.Printf("Worker %d started\n", id)
    time.Sleep(1 * time.Second) // simulate work
    fmt.Printf("Worker %d finished\n", id)
}

func main() {
    const maxConcurrent = 3
    sem := make(chan struct{}, maxConcurrent)
    var wg sync.WaitGroup

    for i := 1; i <= 10; i++ {
        wg.Add(1)
        go worker(i, sem, &wg)
    }

    wg.Wait()
}

In this example, no more than 3 goroutines will run simultaneously.