Как реализовать worker pool в Go и ограничить число горутин?

Как в Go создать worker pool для обработки задач? параллельно выполнять функции с помощью goroutines ограничивать количество активных воркеров через канал-буфер или семафор передавать задания рабочим горутинам через…

Короткий ответ

Что ответить на собеседовании

Как в Go создать worker pool для обработки задач? параллельно выполнять функции с помощью goroutines ограничивать количество активных воркеров через канал-буфер или семафор передавать задания рабочим горутинам через канал задач (job queue) каждый воркер получает задачу из канала, обрабатывает её и отправляет результат для ожидания завершения применяют WaitGroup собирать результаты можно через отдельный канал (fan-in) подход помогает повысить эффективность и управлять параллелизмом

Подробный разбор

Ответ с пояснениями

Как в Go создать worker pool для обработки задач?

  • параллельно выполнять функции с помощью goroutines
  • ограничивать количество активных воркеров через канал-буфер или семафор
  • передавать задания рабочим горутинам через канал задач (job queue)
  • каждый воркер получает задачу из канала, обрабатывает её и отправляет результат
  • для ожидания завершения применяют WaitGroup
  • собирать результаты можно через отдельный канал (fan-in)
  • подход помогает повысить эффективность и управлять параллелизмом

Пример:

jobs := make(chan Job, N)
results := make(chan Result, N)
var wg sync.WaitGroup

worker := func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}

wg.Add(numWorkers)
for i := 0; i < numWorkers; i++ {
go worker()
}

for _, job := range jobList {
jobs <- job
}
close(jobs)

wg.Wait()
close(results)

  • worker pool — эффективный способ управления конкурентными задачами с контролем числа горутин
  • помогает не создавать избыточное количество горутин и уменьшает нагрузку
  • часто применяется в веб-серверах, обработчиках очередей, парсерах и других подобных задачах

Развёрнутый ответ

Краткий ответ

В Go worker pool — это шаблон параллельной обработки, при котором задачи выполняет заранее ограниченное число горутин-воркеров. Они получают задания из общей очереди, представленной каналом, и обрабатывают их. Благодаря этому система контролирует расход ресурсов и не создаёт чрезмерное число горутин.

Основные особенности

  • В состав решения входят канал задач (job channel), заданное количество горутин-воркеров, читающих из него и обрабатывающих задания, а также основной цикл, передающий задачи в канал.
  • Для управления жизненным циклом воркеров и своевременной остановки применяют контекст (context.Context) и WaitGroup.
  • Такой подход помогает избежать гонок и дедлоков: каналы Go потокобезопасны и удобны для синхронизации взаимодействия горутин.

Последовательность реализации

  1. Сначала создаём канал задач, например, jobs := make(chan Job).
  2. Затем запускаем N горутин-воркеров. Каждая в цикле читает задания из jobs и обрабатывает их.
  3. Основная горутина отправляет задания в jobs, а по завершении отправки закрывает канал, чтобы воркеры поняли, что работа закончена.
  4. Для ожидания окончания работы всех воркеров используем sync.WaitGroup.

Практическое применение

Worker pool используют для запросов к внешним API, параллельной обработки файлов, а также работы с очередями из базы данных или брокеров сообщений. В Go 1.20+ для управления группами горутин и обработки ошибок можно применять встроенный пакет sync/errgroup.

Этот шаблон уменьшает нагрузку на систему, не допускает чрезмерного расхода памяти и CPU и помогает сохранять стабильную производительность при большом количестве задач.

Практика в реальном времени

Подготовьтесь к следующему собеседованию

Interview Boost учитывает вакансию, резюме и технологии и помогает сформулировать ответ прямо во время интервью.

Начать подготовку