2017-02-24 1 views
3

Ich weiß, dass Golang bytes.Buffer nicht threadsicher ist, aber wenn ich einen Schreiber (in einer Goroutine) und einen Leser (in einer anderen Goroutine) habe. Ist es sicher?Golans Bytes.Buffer Thread Sicherheit für einen Schreiber/einen Leser

Wenn nicht, warum nicht? Schreiben fügt an den Puffer an, während Lesevorgänge vom Anfang gelesen werden, so dass ich kein Szenario sehe, in dem sie auf den gleichen Speicherort zugreifen.

Antwort

8

Nein, es ist nicht sicher.

bytes.Buffer ist ein struct und beide Buffer.Read() und Buffer.Write() Methoden Lese-/die gleichen Felder der gleichen struct Wert ändern (sie haben pointer Empfänger). Dies alleine reicht aus, um für die gleichzeitige Verwendung unsicher zu sein. Weitere Details finden Sie unter Is it safe to read a function pointer concurrently without a lock?

Denken Sie auch daran, dass eine bytes.Buffer Bytes in einem Byte-Slice speichert, das ein Feld der Struktur ist. Beim Schreiben kann es erforderlich sein, manchmal einen größeren Puffer zuzuweisen (wenn die Schichtkapazität nicht ausreicht), und daher muss der Schichtkopf (das Schichtstrukturfeld) geändert werden (in Write()). Ohne Synchronisierung gibt es keine Garantie dafür, dass ein gleichzeitiger Read() dies sehen wird.

Und ... auch wenn keine Umverteilung benötigt wird (da die zugrunde liegende Byte Scheibe genügend Kapazität hat, die Daten zu Write() weitergegeben aufzunehmen), erfordert die Daten in der Byte-Scheibe zu speichern, es zu partitionieren, so dass die Kopfscheibe ändert sich auch wenn keine Neuzuweisung erforderlich ist (die Länge des Slice ist ebenfalls Teil des Slice-Headers). Um zu sehen, was in der Scheibenkopfzeile ist, überprüfen Sie den reflect.SliceHeader Typ.