В този пример ще видим как се осъществява работилница1 с помощта на гозадачи и канали.
import (
"fmt"
"time"
)
Ето я заготовката за работник, от която ще създадем
няколко съработни1 единици2.
Тези работници ще получават работа, по канала работа
и ще изпращат произведенията си по канала
произведено. Ще накараме всяка гозадача да заспи за
секунда, за да наподобим времеемка, сиреч скъпоструваща
задача.
func работник(id int,
работа <-chan int, произведено chan<- int) {
for j := range работа {
fmt.Println("работник", id, "започна задача", j)
time.Sleep(time.Second)
fmt.Println("работник", id, "завърши задача", j)
произведено <- j * 2
}
}
func main() {
За да ползваме нашата работилница с работници,
трябва да им изпратим задачи и да съберем
произведенето от всеки работник. За целта правим
(make) два канала.
const бройЗадачи = 5
задачи := make(chan int, бройЗадачи)
произведено := make(chan int, бройЗадачи)
Тук създаваме три работника, които в началото не работят, защото все още нямат задачи.
for w := 1; w <= 3; w++ {
go работник(w, задачи, произведено)
}
Тук изпращаме пет задачи и после затваряме с
помощта на close канала, за да кажем, че това е
всичко, което искаме да се изработи.
for j := 1; j <= бройЗадачи; j++ {
задачи <- j
}
close(задачи)
Накрая събираме всичко произведено. Това изявление също така обезпечава приключването на всички гозадачи-работници. Иначе програмата би завършила без да чака работниците. Друг начин да чакаме множество гозадачи е като си създадем чакалня[^wgroup] с помощта на WaitGroup. [^wgroup]: wait-group – (за целите на превода) чакалня, иначе – изчакване на множество гозадачи.
for a := 1; a <= бройЗадачи; a++ {
произведение := <-произведено
fmt.Println("Произведено:", произведение)
}
}
Работещата ни програма показва, че петте задачи биват извършвани от различни работници Програмата се изпълнява само за 2 секунди и нещо, макар всяка задача да отнема по секунда и нещо. За 2 секунди е свършена работа, отнемаща общо над 5 секунди, защото трите работника работеха едновременно.
$ time go run worker-pools.go
работник 3 започна задача 1
работник 1 започна задача 2
работник 2 започна задача 3
работник 2 завърши задача 3
работник 2 започна задача 4
Произведено: 6
работник 1 завърши задача 2
работник 1 започна задача 5
Произведено: 4
работник 3 завърши задача 1
Произведено: 2
работник 1 завърши задача 5
Произведено: 10
работник 2 завърши задача 4
Произведено: 8
real 0m2,232s
Следващ пример: Чакални.