Heim >Backend-Entwicklung >Golang >Ist das Ersetzen einer zugeordneten Variablen durch einen neuen zugeordneten Objektthread sicher?
PHP-Editor Apple ist hier, um eine häufig gestellte Frage zu beantworten: „Ist es threadsicher, eine Mapping-Variable durch ein neues Mapping-Objekt zu ersetzen?“ Eine Mapping-Variable ist eine allgemeine Datenstruktur, die zum Speichern von Schlüssel-Wert-Paaren verwendet wird. In einer Multithread-Umgebung ist die Thread-Sicherheit ein wichtiger Gesichtspunkt. Obwohl die Verwendung eines neuen Zuordnungsobjekts das Problem des gleichzeitigen Zugriffs vermeiden kann, muss die Thread-Sicherheit immer noch von Fall zu Fall beurteilt werden. Als nächstes werden wir dieses Problem eingehend untersuchen, um den Lesern zu helfen, die Beziehung zwischen Thread-Sicherheit und zugeordneten Objekten besser zu verstehen.
Ich glaube nicht, dass es Thread-sicher ist, da das zugeordnete Objekt größer als Maschinenwörter ist und Golang nicht garantiert, dass es Thread-sicher ist. Aber wenn ich den Democode mit go run -race main.go
ausführe, wird nie ein Fehler gemeldet. Dies kann der Grund sein, warum Threadsanitizer auf Laufzeitprüfungen und Zuweisungsvorgänge angewiesen ist, um die Erfüllung unsicherer Thread-Bedingungen zu erschweren.
Hier ist der Beispielcode:
package main import ( "fmt" ) var m = make(map[int]bool) func Read() { for { for k := range m { fmt.Println(k) } } } func Replace() { for { newM := make(map[int]bool, 10) for i := 0; i < 10; i++ { newM[i] = false } m = newM } } func main() { c := make(chan struct{}) go Read() go Replace() <-c }
Wie ändere ich den Code, um Parallelitätsfehler auszulösen? Oder irre ich mich vielleicht und der Code ist Thread-sicher?
Hier sind ein paar Punkte zu beachten:
for k := range m {
Range-Ausdrücke werden einmal am Anfang der for-Schleife ausgewertet. Diese Operation lautet also m
一次(注意,这意味着如果循环中的代码重新分配 m
,则循环将继续迭代原始 m
,但是如果添加新元素或从 m
中删除元素,这些将被检测到循环),循环本身会调用 fmt.println
, was die meiste Ausführungszeit in dieser Goroutine in Anspruch nimmt. Wenn Sie das Spiel nachholen möchten, löschen Sie es.
Zweitens müssen Sie die zweite Karte nicht wirklich initialisieren.
Wenn Sie dies tun und den Renndetektor ausführen, kann es sein, dass Datenrennen erfasst werden. Soweit es mich betrifft, ist es so.
Der Konfliktdetektor meldet einen Konflikt, wenn er ihn erkennt. Wenn also eine Übereinstimmung gemeldet wird, liegt eine Übereinstimmung vor. Wenn es nicht gemeldet wird, heißt das nicht, dass es keinen Wettbewerb gibt.
Auf meiner Plattform hat die Map-Variable selbst tatsächlich die gleiche Größe wie ein Maschinenwort: Sie ist nur ein Zeiger auf die abgebildete Struktur. Daher sind Schreibvorgänge in zugeordnete Variablen effektiv atomar, d. h. Sie werden auf dieser Plattform keine teilweise zugewiesenen Zuordnungen sehen. Dies verhindert jedoch keinen Konflikt, da es keine Garantie dafür gibt, wann andere Goroutinen diesen Speicherschreibvorgang sehen.
Kurz gesagt, es ist ein Wettbewerb. Dies liegt nicht an der Größe der Kartenvariablen. Um dies zu beheben, verwenden Sie einen Mutex.
Das obige ist der detaillierte Inhalt vonIst das Ersetzen einer zugeordneten Variablen durch einen neuen zugeordneten Objektthread sicher?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!