Контроль количества одновременных запусков функции printNumber без её изменения

Код уже ограничивает одновременное выполнение участка после отправки в sem пятью вызовами. Буфер канала заполнится, и остальные 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 внутри функции обычное освобождение в конце было бы недостаточным.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее