Код уже ограничивает одновременное выполнение участка после отправки в sem пятью вызовами. Буфер канала заполнится, и остальные printNumber будут ждать освобождения места.
Контроль количества одновременных запусков функции printNumber без её изменения
Код уже ограничивает одновременное выполнение участка после отправки в sem пятью вызовами. Буфер канала заполнится, и остальные printNumber будут ждать освобождения места.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо реализовать ограничитель, который не позволит функции printNumber выполняться более пяти раз одновременно, при этом саму функцию менять нельзя.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wgGroup := sync.WaitGroup{}
sem := make(chan struct{}, 5)
for idx := 0; idx < 10; idx++ {
wgGroup.Add(1)
go func(num int) {
defer wgGroup.Done()
printNumber(sem, num)
}(idx)
}
wgGroup.Wait()
close(sem)
}
func printNumber(ch chan struct{}, n int) {
ch <- struct{}{}
time.Sleep(time.Second)
fmt.Println(n)
<-ch
}
Ответ
Код уже ограничивает одновременное выполнение участка после отправки в sem пятью вызовами. Буфер канала заполнится, и остальные printNumber будут ждать освобождения места.
Все десять горутин при этом созданы сразу: ограничены активные участки, не общее число горутин. WaitGroup дожидается завершения, после чего close безопасен, хотя не обязателен. Не захватывайте тот же sem повторно в обёртке: функция сама уже берёт токен и это может вызвать deadlock. Для ограничения числа созданных горутин используйте отдельный внешний пул. При возможной panic внутри функции обычное освобождение в конце было бы недостаточным.