Go by Example - IT: Chiudere Channel

Chiudere un channel serve ad indicare che non verranno più inviati su quel channel. Questo è utile per comunicare il completamento di un operazione a chi sta ascoltando sul channel.

package main
import "fmt"

In questo esempio useremo un channel jobs per inviare i task che devono essere eseguiti dalla goroutine main() a una goroutine che svolge il ruolo di worker. Quando non si hanno più task da eseguire si chiuderà il channel jobs tramite il built-in close.

func main() {
    jobs := make(chan int, 5)
    done := make(chan bool)

Questa è la goroutine worker, che riceverà i task in modo continuativo dal channel jobs tramite il comando j, more := <-jobs. Utilizzando questa forma speciale per ricevere i valori, nella variabile more avremo il valore false se il channel jobs è stato chiuso e tutti i valori sono stati ricevuti. Utilizzeremo questo valore per indicare quando la goroutine ha terminato di eseguire tutti i task che ha ricevuto.

    go func() {
        for {
            j, more := <-jobs
            if more {
                fmt.Println("received job", j)
            } else {
                fmt.Println("received all jobs")
                done <- true
                return
            }
        }
    }()

Questo invia 3 job alla goroutine worker sul channel jobs e lo chiude subito dopo.

    for j := 1; j <= 3; j++ {
        jobs <- j
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")

Attendiamo la goroutine worker utilizzando l’approccio di sincronizzazione che abbiamo visto negli esempi precedenti

    <-done
}
$ go run closing-channels.go 
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs

L’esempio che segue deriva direttamente dal concetto di chiusura di un channel: come effettuare un range su un channel.

Prossimo esempio: Range sui Channel.