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.