|
V tomto příkladu se podíváme jak naimplementovat zásobníky pracovních rutin (worker pools) s pomocí gorutin a kanálů. |
|
package main
|
|
import "fmt"
import "time"
|
|
|
Tady je pracovní rutina které spustíme několik instancí
soubežně. Tyto rutiny přijmou práce na kanálu |
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "nastartoval job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "ukončil job", j)
results <- j * 2
}
}
|
func main() {
|
|
|
Pro náš zásobník rutin jim budeme chtít poslat práci a pak přijmout a poté posbírat jejich výsledky. K tomu si vytvoříme 2 kanály. |
jobs := make(chan int, 100)
results := make(chan int, 100)
|
|
Tohle nastartuje 3 pracovní rutiny, nejdřív zablokované, protože ještě nemají žádnou práci v kanálu jobs. |
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
|
|
Zde pošleme 5 |
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
|
|
Na závěr posbíráme všechny výsledky práce. To také zajistí že pracovní gorutiny skončily. Alternativně můžeme také počkat na víc gorutin s použitím Čekání na skupiny s WaitGroup. |
for a := 1; a <= 5; a++ {
<-results
}
}
|
|
Náš běžící program ukazuje že se provádí 5 úkolů různými pracovními rutinami. Program běžá jenom asi 2 vteřiny ačkoliv pracujeme na celkové práci okolo 5 vteřin, to je proto, že 3 rutiny běží souběžné. |
$ time go run worker-pools.go
worker 3 nastartoval job 1
worker 1 nastartoval job 2
worker 2 nastartoval job 3
worker 1 ukončil job 2
worker 1 nastartoval job 4
worker 3 ukončil job 1
worker 3 nastartoval job 5
worker 2 ukončil job 3
worker 3 ukončil job 5
worker 1 ukončil job 4
|
real 0m2.358s
|
Další příklad: Čekání na skupiny s WaitGroup.