In Go können Werte jeden Typs über Kanäle gesendet werden: int, struct, Zeiger, Interfaces usw.
Code und Beispiel:
type Data struct { N int } c := make(chan Data) d := Data{N: 1} c <- d // die gesamte Struktur wird kopiert p := &Data{N: 3} c2 := make(chan *Data) c2 <- p // der Zeiger auf dasselbe Objekt wurde über den Kanal gesendet
Wenn eine Struktur, die ein Zeigerfeld enthält, über den Kanal gesendet wird — wird es dann eine Race Condition geben, wenn dieses Feld an beiden Enden des Kanals geändert wird?
Antwort:
Beispiel:
type Box struct { Ptr *int } x := 10 chanBox := make(chan Box) chanBox <- Box{Ptr: &x} // sowohl Sender als auch Empfänger haben Zugriff auf x!
Geschichte
In der verteilten Warteschlange gab es häufige „zufällige“ Abstürze und mysteriöse Werte in der Aufgabenstruktur. Es stellte sich heraus, dass Zeiger auf gemeinsame Strukturen über den Kanal übertragen wurden, die parallel in mehreren Goroutinen geändert wurden. Man entschied sich, die Übertragung auf Kopien der Daten umzustellen.
Geschichte
Die asynchrone Verarbeitung von Nachrichten arbeitete mit Strukturen, die Zeiger-Slices auf ein gemeinsames Array enthielten. Bei paralleler Übertragung über den Kanal wurden Teile desselben Speichers an verschiedenen Stellen geändert, was zu geheimen Bugs und Datenbeschädigungen führte.
Geschichte
Im Push-Benachrichtigungsdienst wurden Links auf Objekte über den Kanal übertragen, die dann von Goroutinen verarbeitet wurden. Bei gleichzeitiger Beendigung der Arbeit und Schließung des Kanals wurden einige Strukturen noch modifiziert, was zu Panik oder Datenrennen führte. Der Übergang zur Kopierung der Struktur vor dem Senden half.