In Go è possibile inviare attraverso i canali valori di qualsiasi tipo: int, struct, puntatori, interfacce, ecc.
Codice e esempio:
type Data struct { N int } c := make(chan Data) d := Data{N: 1} c <- d // struttura copiata interamente p := &Data{N: 3} c2 := make(chan *Data) c2 <- p // inviato attraverso il canale un puntatore allo stesso oggetto
Se attraverso il canale viene passata una struttura che contiene un campo-puntatore — ci sarà condizione di race durante la modifica di questo campo da entrambe le estremità del canale?
Risposta:
Esempio:
type Box struct { Ptr *int } x := 10 chanBox := make(chan Box) chanBox <- Box{Ptr: &x} // sia il mittente che il destinatario hanno accesso a x!
Storia
Nella coda distribuita ci sono stati frequenti “casuali” crash e valori misteriosi nella struttura del compito. Si è scoperto che venivano inviati puntatori a strutture condivise che venivano modificate contemporaneamente in più goroutine. Si è deciso di passare alle copie dei dati.
Storia
L'elaborazione asincrona dei messaggi lavorava con strutture che contenevano slice-puntatori a un array comune. Durante la trasmissione parallela, parti della stessa memoria venivano modificate da diverse posizioni, portando a bug misteriosi e corruzione dei dati.
Storia
Nel servizio di notifiche push venivano passati riferimenti a oggetti, che venivano poi elaborati da goroutine. Durante la chiusura simultanea del lavoro e del canale, alcune strutture venivano ancora modificate, causando panico o race condition. Si è risolto passando alla copia della struttura prima dell'invio.