Golang Worker pool
В Go (Golang) можно реализовать пул воркеров (worker pool) для выполнения задач в параллельных горутинах. Пул воркеров позволяет ограничить количество одновременно выполняемых задач, что полезно для управления нагрузкой и ресурсами.
Ниже приведен пример реализации простого пула воркеров на Go:
Код пула воркеров
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package main import ( "fmt" "sync" "time" ) // Task представляет собой задачу, которую нужно выполнить. type Task struct { ID int } // Worker представляет собой воркера, который выполняет задачи. func Worker(id int, tasks <-chan Task, wg *sync.WaitGroup) { defer wg.Done() // Уменьшаем счетчик WaitGroup при завершении воркера for task := range tasks { fmt.Printf("Worker %d started task %d\n", id, task.ID) time.Sleep(time.Second) // Имитация выполнения задачи fmt.Printf("Worker %d finished task %d\n", id, task.ID) } } func main() { const numWorkers = 3 // Количество воркеров const numTasks = 10 // Количество задач tasks := make(chan Task, numTasks) // Канал для задач var wg sync.WaitGroup // WaitGroup для ожидания завершения воркеров // Запускаем воркеров for i := 1; i <= numWorkers; i++ { wg.Add(1) go Worker(i, tasks, &wg) } // Отправляем задачи в канал for i := 1; i <= numTasks; i++ { tasks <- Task{ID: i} } close(tasks) // Закрываем канал задач после отправки всех задач wg.Wait() // Ожидаем завершения всех воркеров fmt.Println("All tasks are completed") } |
Как это работает?
- Канал задач (
tasks
):- Канал
tasks
используется для передачи задач воркерам. - Размер буфера канала равен количеству задач (
numTasks
), чтобы избежать блокировки при отправке задач.
- Канал
- Воркеры:
- Каждый воркер — это горутина, которая читает задачи из канала
tasks
и выполняет их. - Воркеры работают параллельно, но их количество ограничено (
numWorkers
).
- Каждый воркер — это горутина, которая читает задачи из канала
- WaitGroup:
sync.WaitGroup
используется для ожидания завершения всех воркеров.- Каждый воркер уменьшает счетчик
WaitGroup
при завершении.
- Отправка задач:
- Задачи отправляются в канал
tasks
. - После отправки всех задач канал закрывается с помощью
close(tasks)
.
- Задачи отправляются в канал
- Завершение:
- Программа ждет завершения всех воркеров с помощью
wg.Wait()
.
- Программа ждет завершения всех воркеров с помощью
Преимущества пула воркеров
- Ограничение количества горутин:
- Пул воркеров позволяет ограничить количество одновременно работающих горутин, что полезно для управления ресурсами.
- Параллельное выполнение задач:
- Задачи выполняются параллельно, что ускоряет обработку.
- Простота управления:
- Использование каналов и
WaitGroup
делает код простым и понятным.
- Использование каналов и
Дополнительные улучшения
- Обработка ошибок:
- Можно добавить канал для ошибок, чтобы воркеры могли сообщать об ошибках.
- Динамическое изменение количества воркеров:
- Количество воркеров можно изменять динамически в зависимости от нагрузки.
- Приоритеты задач:
- Можно использовать несколько каналов для задач с разными приоритетами.
Recommended Posts
Golang map и Swiss Table
16.03.2025