Wednesday, January 14, 2026

goroutine - 3 - Buffered Channel as Semaphore (Classic Go Pattern)

 package main


import (

"fmt"

"sync"

"time"

)


func processTask(taskID int, sem chan struct{}, results chan<- string) {

defer func() { <-sem }() // Release the semaphore

// Simulate work

time.Sleep(time.Millisecond * time.Duration(100+taskID*10))

results <- fmt.Sprintf("Task %d completed", taskID)

}


func main() {

const totalTasks = 50

const maxConcurrency = 10

sem := make(chan struct{}, maxConcurrency)

results := make(chan string, totalTasks)

var wg sync.WaitGroup

// Launch tasks

for i := 1; i <= totalTasks; i++ {

wg.Add(1)

go func(taskID int) {

defer wg.Done()

sem <- struct{}{} // Acquire semaphore

processTask(taskID, sem, results)

}(i)

}

// Wait for all tasks

go func() {

wg.Wait()

close(results)

}()

// Collect results

var completed []string

for result := range results {

completed = append(completed, result)

fmt.Println(result)

}

fmt.Printf("\nSummary: Completed %d tasks with max %d concurrent workers\n", 

len(completed), maxConcurrency)

}

No comments:

Post a Comment