Bufferizzazione
Un channel normale contiene esattamente un valore. E' possibile creare channel che contengono più di un valore, dando il loro numero come secondo argomento all'atto della creazione.
Si ottiene un channel bufferizzato, con lunghezza del buffer indicata.
Esempio
(240channel-buffering.go):
package main
import "fmt"
func main() {
// Di default i channel non sono bufferizzati
// e accettano un send solo se il receive è attivo
// Di seguito è creato un canale bufferizzato
// con fino a 2 valori
messages := make(chan string, 2)
// Si possono bufferizzare i valori senza
// che vi sia ancora il receive
messages <- "buffered"
messages <- "channel"
// Il receive avviene più tardi
fmt.Println(<-messages)
fmt.Println(<-messages)
// Se si toglie il commento si genera un blocco
// fmt.Println(<-messages)
}
Regole
Le regole sono:
- ogni read toglie un valore dal channel
- se il channel è vuoto in read la routine si blocca
- se il channel è pieno in write la routine si blocca
Nell'esempio corrente il channel è scritto e letto dal main. Questa non è una buona idea.
Un channel non dovrebbe mai essere sia letto che scritto dalla stessa routine.
Se il main si blocca e non vi è nessun'altra routine attiva che lo sblocchi si causa un Deadlock, con conseguente panic.
Il Go ha un modulo di detezione dei Deadlock a runtime, purtroppo però non durante la compilazione.