W Go można przesyłać przez kanały wartości dowolnego typu: int, struct, wskaźniki, interfejsy itd.
Kod i przykład:
type Data struct { N int } c := make(chan Data) d := Data{N: 1} c <- d // cała struktura jest kopiowana p := &Data{N: 3} c2 := make(chan *Data) c2 <- p // przez kanał przesyłany jest wskaźnik do tego samego obiektu
Czy jeśli przez kanał przesłać strukturę zawierającą pole-wskaźnik — czy wystąpi race condition przy zmianie tego pola z obu końców kanału?
Odpowiedź:
Przykład:
type Box struct { Ptr *int } x := 10 chanBox := make(chan Box) chanBox <- Box{Ptr: &x} // zarówno nadawca, jak i odbiorca mają dostęp do x!
Historia
W rozproszonej kolejce występowały częste "przypadkowe" awarie i tajemnicze wartości w strukturze zadania. Okazało się, że przez kanał przesyłano wskaźniki do wspólnych struktur, które były równolegle modyfikowane w kilku gorutynach. Postanowiono zmienić metodę na przesyłanie kopii danych.
Historia
Asynchroniczna obróbka wiadomości działała ze strukturami, w których były slice-wskaźniki na wspólną tablicę. Przy równoległym przesyłaniu przez kanał część tej samej pamięci była modyfikowana z różnych miejsc, co prowadziło do ukrytych błędów i uszkodzenia danych.
Historia
W serwisie powiadomień push przez kanał przesyłano wskaźniki do obiektów, które były następnie przetwarzane przez gorutyny. Przy jednoczesnym kończeniu pracy i zamykaniu kanału część struktur nadal była modyfikowana, co powodowało panikę lub race data. Pomogło przejście na kopiowanie struktury przed wysłaniem.