Приведённый код уже ограничивает число одновременных printNumber тремя: вход в функцию возможен только после получения слота в канале.
Установить максимум одновременно запущенных вызовов функции printNumber
Приведённый код уже ограничивает число одновременных printNumber тремя: вход в функцию возможен только после получения слота в канале.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Модифицируйте программу так, чтобы одновременно выполнялось не более трёх вызовов функции printNumber.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
sem := make(chan struct{}, 3) // семафор, ограничивающий количество одновременных вызовов
for idx := 0; idx < 10; idx++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
sem <- struct{}{} // захватываем слот
printNumber(n)
<-sem // освобождаем слот
}(idx)
}
wg.Wait()
}
func printNumber(num int) {
time.Sleep(time.Second)
fmt.Println(num)
}
Ответ
Приведённый код уже ограничивает число одновременных printNumber тремя: вход в функцию возможен только после получения слота в канале.
Созданных горутин будет десять, но одновременно внутри printNumber — не больше трёх. Остальные ждут отправки в заполненный sem. WaitGroup корректно ждёт их завершения.
Небольшое улучшение: после sem <- struct{}{} выполнить defer func() { <-sem }(), чтобы освобождение слота не зависело от будущих ранних return. Если необходимо ограничить и количество живых горутин, слот захватывают перед go или используют фиксированный пул работников. Это другое ограничение, которого текущая задача не требует.