Go'da herhangi bir türdeki değerleri kanallar aracılığıyla göndermek mümkündür: int, struct, işaretçiler, arayüzler vb.
Kod ve örnek:
type Data struct { N int } c := make(chan Data) d := Data{N: 1} c <- d // yapı tamamen kopyalanır p := &Data{N: 3} c2 := make(chan *Data) c2 <- p // kanaldan aynı nesneye işaretçi gitti
Eğer bir kanala bir işaretçi alanı içeren bir yapı gönderilirse - kanaldan her iki uçta bu alanı değiştirildiğinde race condition olur mu?
Cevap:
Örnek:
type Box struct { Ptr *int } x := 10 chanBox := make(chan Box) chanBox <- Box{Ptr: &x} // hem gönderen hem de alıcı x'e erişime sahip!
Hikaye
Dağıtılmış kuyrukta sıkça "rastgele" çökme ve görev yapısında gizemli değerler vardı. Kanal aracılığıyla ortak yapılar üzerinde değişiklik yapan işaretçileri gönderiyorlardı. Veri kopyalarına geçilmesine karar verildi.
Hikaye
Asenkron mesaj işleme, içinde ortak diziye işaretçiler bulunan yapılarla çalışıyordu. Parallelde kanal aracılığıyla aynı bellek kısmı farklı yerlerden değiştiriliyordu, bu da gizli hatalara ve veri bozulmasına yol açıyordu.
Hikaye
Push bildirimleri servisi, işaretçileri işleyen goroutinelar tarafından daha sonra işlenen nesnelere kanal aracılığıyla iletiliyordu. Kanal kapatılırken, bazı yapılar hala değiştirilerek panik veya veri yarışı yaratıyordu. Göndermeden önce yapı kopyalamaya geçmek işe yaradı.