воркер пулы

This commit is contained in:
badkaktus 2019-10-08 12:23:00 +03:00
parent c2562c4af9
commit 77e54d9f74
3 changed files with 24 additions and 23 deletions

View File

@ -31,7 +31,7 @@ Select
Перебор значений из каналов (Range over Channels) Перебор значений из каналов (Range over Channels)
Таймеры (Timers) Таймеры (Timers)
Тикеры (повторения) (Tickers) Тикеры (повторения) (Tickers)
Worker Pools Пулы воркеров (Worker Pools)
WaitGroups WaitGroups
Rate Limiting Rate Limiting
Atomic Counters Atomic Counters

View File

@ -1,5 +1,6 @@
// In this example we'll look at how to implement // В этом примере мы рассмотрим, как реализовать
// a _worker pool_ using goroutines and channels. // _пул воркеров_ с использованием каналов и
// горутин.
package main package main
@ -8,11 +9,11 @@ import (
"time" "time"
) )
// Here's the worker, of which we'll run several // Это воркер, который мы будем запускать в нескольких
// concurrent instances. These workers will receive // параллельных инстансах. Эти воркеры будут получать
// work on the `jobs` channel and send the corresponding // задания через канал `jobs` и отсылать результаты
// results on `results`. We'll sleep a second per job to // в `results`. Мы будем ожидать одну секунду для
// simulate an expensive task. // каждого задания для имитации тяжелого запроса.
func worker(id int, jobs <-chan int, results chan<- int) { func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs { for j := range jobs {
fmt.Println("worker", id, "started job", j) fmt.Println("worker", id, "started job", j)
@ -24,29 +25,29 @@ func worker(id int, jobs <-chan int, results chan<- int) {
func main() { func main() {
// In order to use our pool of workers we need to send // Чтобы использовать наш воркер пул, нам нужно
// them work and collect their results. We make 2 // отправить им задание и получить результаты выполнения.
// channels for this. // Для этого мы делаем 2 канала.
jobs := make(chan int, 100) jobs := make(chan int, 100)
results := make(chan int, 100) results := make(chan int, 100)
// This starts up 3 workers, initially blocked // Стартуем 3 воркера, первоначально заблокированных,
// because there are no jobs yet. // т.к. еще нет заданий.
for w := 1; w <= 3; w++ { for w := 1; w <= 3; w++ {
go worker(w, jobs, results) go worker(w, jobs, results)
} }
// Here we send 5 `jobs` and then `close` that // Посылаем 5 `заданий (jobs)` и затем `закрываем`
// channel to indicate that's all the work we have. // канал, сообщая о том что все задания отправлены.
for j := 1; j <= 5; j++ { for j := 1; j <= 5; j++ {
jobs <- j jobs <- j
} }
close(jobs) close(jobs)
// Finally we collect all the results of the work. // Наконец мы собираем все результаты. Это также
// This also ensures that the worker goroutines have // гарантирует, что горутины закончились. Альтернативный
// finished. An alternative way to wait for multiple // способ ожидания нескольких процедур заключается
// goroutines is to use a [WaitGroup](waitgroups). // в использовании [WaitGroup](waitgroups).
for a := 1; a <= 5; a++ { for a := 1; a <= 5; a++ {
<-results <-results
} }

View File

@ -1,7 +1,7 @@
# Our running program shows the 5 jobs being executed by # Наша программа показывает 5 заданий, выполняемых
# various workers. The program only takes about 2 seconds # различными воркерами. Программа занимает всего около
# despite doing about 5 seconds of total work because # 2 секунд, несмотря на выполнение около 5 секунд общей
# there are 3 workers operating concurrently. # работы, потому что одновременно работают 3 воркера.
$ time go run worker-pools.go $ time go run worker-pools.go
worker 1 started job 1 worker 1 started job 1
worker 2 started job 2 worker 2 started job 2