Worker Pool

Worker Pool #

// In questo esempio vedremo come implementare
// un _worker pool_ usando le goroutine e i channel.

package main

import "fmt"
import "time"

// Questo è il worker, sul quale eseguiremo i nostri
// task concorrenti. Questi worker riceveranno i task da
// eseguire sul channel `jobs` ed invieranno i risultati sul
// channel `results`. In questo esempio abbiamo inserito una
// `Sleep` da un secondo per simulare un task oneroso.
func worker(id int, jobs <-chan int, results chan<- int) {
    for j := range jobs {
        fmt.Println("worker", id, "sta eseguendo task", j)
        time.Sleep(time.Second)
        results <- j * 2
    }
}

func main() {

    // Per poter utilizzare il pool di worker dobbiamo
    // poter inviare i task e poter ricevere i risultati,
    // creiamo dunque due channel per questo
    jobs := make(chan int, 100)
    results := make(chan int, 100)

    // Questo farà partire 3 worker, che saranno inizialmente
    // bloccati in quanto non hanno task da eseguire.
    for w := 1; w <= 3; w++ {
        go worker(w, jobs, results)
    }

    // Inviamo 9 task da eseguire sul channel `job` ed invochiamo
    // la `close` su quel canale, in modo da indicare che non
    // ci sono altri task da eseguire.
    for j := 1; j <= 9; j++ {
        jobs <- j
    }
    close(jobs)

    // Infine recuperiamo i risultati delle computazioni sul
    // channel `results`
    for a := 1; a <= 9; a++ {
        <-results
    }
}
# Il nostro programma in esecuzione mostra i 9 task
# che vengono eseguiti dai vari worker. Il programma
# termina in circa 3 secondi, anche se il totale dei
# task avrebbe richiesto 9 secondi. Questo perchè ci
# sono 3 worker che vengono eseguiti in parallelo
$ time go run worker-pools.go 
worker 1 sta eseguendo task job 1
worker 2 sta eseguendo task job 2
worker 3 sta eseguendo task job 3
worker 1 sta eseguendo task job 4
worker 2 sta eseguendo task job 5
worker 3 sta eseguendo task job 6
worker 1 sta eseguendo task job 7
worker 2 sta eseguendo task job 8
worker 3 sta eseguendo task job 9

real	0m3.149s