2015-04-07 27 views
10

Ist es sicher, auf verschiedene Strukturelemente aus verschiedenen Gruoutinen zuzugreifen?Ist es Thread sicher, auf verschiedene Mitglieder von struct in go zuzugreifen?

Ich verstehe, dass ohne Synchronisation auf die gleiche Variable Schreiben dangareous ist:

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.color = "green" 
    }() 
} 

Aber können Sie auf verschiedene Strukturkomponenten ohne jede Art von Synchronisation schreiben?

package main 

type Apple struct { 
    color string 
    size uint 
} 

func main() { 
    apple := &Apple{} 
    go func() { 
     apple.color = "red" 
    }() 
    go func() { 
     apple.size = 42 
    }() 
} 

Oder sollte ich chan oder sync.Mutex für das?

Antwort

11

Es sollte sicher sein, auf verschiedene Variablen aus verschiedenen Threads zuzugreifen, und Strukturelemente sind verschiedene Variablen. Also ja, es sollte sicher sein.

Es kann jedoch nicht schnell sein. Variablen, die wie Strukturelemente im Speicher nahe beieinander liegen, teilen sich eine CPU-Cache-Zeile. Eine Cache-Zeile ist das kleinste Stück Speicher, das eine CPU (also die meisten aktuellen Modelle) sperren kann. Das bedeutet, dass CPU-2 warten muss, um zu schreiben, bis CPU-1 mit dieser Cache-Zeile fertig ist, selbst wenn sie auf verschiedene Variablen schreiben.

Es ist NICHT sicher, den Zeiger auf die Struktur zu ändern, während aus verschiedenen Threads in die Struktur geschrieben wird. In Ihrem Beispiel, wenn Sie eine dritte goroutine hatten, die apple = &Apple{} einige der anderen goroutines in anderen Threads geschrieben haben könnte auf den alten Apple oder den neuen Apple und Sie würden nicht wissen.

+3

Die Absätze 1 und 3 sind großartig; Absatz 2 erscheint off-topic (weil die Sorge Sicherheit ist) und schlechter Rat (weil Go eine solche Hochsprache ist, sollten Sie den aussagekräftigsten Code standardmäßig schreiben und wo nötig von Fall zu Fall optimieren-- nicht, indem man diese Begründung allgemein anwendet, es gibt keine Garantie, dass diese Goroutines sogar von verschiedenen CPUs ausgeführt werden!). – weberc2

+0

Stimmen Sie mit @ weberc2 überein. Während die Frage der falschen Freigabe ein Problem ist, geht es um die Änderung von 2 Variablen mit oder ohne Mutex. Das Cache-Line-Problem mit vorhanden sein, unabhängig davon, welche Antwort richtig ist, und die Lösung wäre unabhängig davon die gleiche. – JimB

+0

@ weberc2: Lustig, weil einer der Gründe, warum ich Go mag, ist, dass es keine so hohe Sprache ist. Es kompiliert ähnlich wie C mit Garbage Collection. –