Chiusura
Questo è un altro esempio dell'uso di due channels tra il main e la goroutine, jos
per l'invio di lavoro vero, e done
per la segnalazione della goroutine ùal main che ha finito di lavorare.
Questo esempio usa un channel dei jobs di capienza bufferizzata superiore all'uso attuale, ed una segnalazione esplicita di terminazione di invio con il comando close
.
Esempio
(300closing-channels.go):
package main
import "fmt"
// Il channel jobs comunica il lavoro da fare
// alla goroutine finchè non viene chiuso
func main() {
// Il comportamento è più verosimile
// se il channel è bloccante, sostituendo
// jobs := make(chan int)
// al seguente
jobs := make(chan int, 5)
done := make(chan bool)
// La goroutine di consumo dei jobs
go func() {
// Loop infinito - spinning
for {
// j è il job, more è un error
// se falso, il channel è stato chiuso
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
// segnala la fine del lavoro
done <- true
return
}
}
}()
// Invia tre job sul channel jobs
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
// Chiude il channel jobs
close(jobs)
fmt.Println("sent all jobs")
// Attende la segnalazione di fine lavoro
<-done
}
Il comando close(jobs)
pone sul channel un segnalino esplicito di terminazione.
La goroutine ad ogni giro del loop legge dal channel un job che ritorna un valore ed un errore, che scatta se viene trovato il segnalino di terminazione.
Dopo un close
la routine scrivente non può più scrivere nel channel.