Шаблон пула работников
Создание пула работников-горутин фиксированного размера
«Шаблон пула работников» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Что такое пул обработчиков
Пул обработчиков заранее создаёт фиксированное число горутин, которые обрабатывают задания из общей очереди. Это ограничивает параллелизм и предотвращает исчерпание ресурсов из-за неограниченного создания горутин.
Базовая реализация
Создайте канал заданий и N горутин, которые будут читать из него:
func workerPool(n int, jobs <-chan Job, results chan<- Result) {
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
wg.Wait()
close(results)
}Отправка заданий
Отправьте все задания в канал, а затем закройте его. Обработчики выполнят все задания и выйдут из циклов перебора после закрытия канала.
jobs := make(chan Job, 100)
for _, j := range allJobs {
jobs <- j
}
close(jobs) // signals workers to stop after drainingСбор результатов
Читайте результаты одновременно с отправкой заданий. Используйте горутину для пула, чтобы сбор результатов не приводил к взаимной блокировке при отправке заданий.
results := make(chan Result, 100)
go workerPool(5, jobs, results)
for r := range results {
collect(r)
}Настройка размера пула
Для работы, ограниченной возможностями CPU, установите размер пула равным runtime.NumCPU(). Для работы, ограниченной вводом-выводом, больший множитель (например, 10×) позволяет эффективнее использовать время ожидания. Проведите профилирование, чтобы найти оптимальное значение.
n := runtime.NumCPU()
if ioHeavy { n = runtime.NumCPU() * 10 }Добавление отмены через контекст
Передавайте контекст обработчикам, чтобы они досрочно останавливались при отмене:
for {
select {
case job, ok := <-jobs:
if !ok { return }
results <- process(ctx, job)
case <-ctx.Done():
return
}
}Альтернатива с семафором
Вместо фиксированного пула горутин используйте буферизованный канал как семафор, чтобы ограничить число одновременно выполняющихся горутин и при этом создавать по одной горутине для каждого задания.
sem := make(chan struct{}, 10)
for _, job := range jobs {
sem <- struct{}{}
go func(j Job) {
defer func() { <-sem }()
process(j)
}(job)
}Обработка ошибок
Возвращайте ошибки вместе с результатами, используя структуру результата. Отменяйте контекст при первой ошибке или собирайте все ошибки для итогового отчёта.
type Result struct{ Val int; Err error }Динамический размер пула
Для адаптивных пулов используйте golang.org/x/sync/semaphore, который позволяет захватывать и освобождать взвешенный ресурс и поддерживает динамические ограничения параллелизма.
Пул обработчиков и errgroup
golang.org/x/sync/errgroup предоставляет более простой интерфейс для запуска N горутин и сбора первой ошибки. Используйте пул, если вам нужен постоянный набор повторно используемых обработчиков.
Корректное завершение
Закройте канал заданий, чтобы подать обработчикам сигнал. После завершения WaitGroup закройте канал результатов. Все ожидающие отправки заданий должны произойти до вызова close(jobs).
Проверка знаний
Как пул обработчиков сообщает обработчикам о необходимости прекратить обработку?
Итоги: пул обработчиков
Главное:
- Фиксированное число N горутин читает из одного канала заданий
- Закройте канал заданий, чтобы сообщить обработчикам о завершении
- WaitGroup отслеживает завершение; после этого закройте канал результатов
- Для задач, ограниченных CPU: размер пула примерно равен NumCPU; для задач, ограниченных вводом-выводом, он должен быть больше
Часто задаваемые вопросы
Урок «Шаблон пула работников» бесплатный?
Да — полный текст урока «Шаблон пула работников» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Шаблон пула работников»?
Создание пула работников-горутин фиксированного размера Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Шаблон пула работников»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Оператор select
- Тайм-ауты и тикеры
- Шаблоны fan-in и fan-out
- Шаблон пула работников