Wenn über eine Karte hin m
die gleichzeitige Schriftsteller, darunter diejenigen, die von der Karte gelöscht werden könnte, ist es nicht Thread-sicher dieseWird in Go ein Wert mit nicht threadsicherem Bereich angezeigt?
for k, v := range m { ... }
Ich denke, Thread-sicher was ich tun ?: zu sein müssen andere mögliche Autoren zu verhindern, den Wert zu ändern v
, während ich es bin zu lesen, und (bei Verwendung eines Mutex und weil Verriegelung einen separaten Schritt ist) überprüfen, ob der Schlüssel k
noch in der Karte ist. Zum Beispiel:
for k := range m {
m.mutex.RLock()
v, found := m[k]
m.mutex.RUnlock()
if found {
... // process v
}
}
(davon ausgehen, dass andere Autoren sind Schreibhemmung m
vor v
ändern.) Gibt es einen besseren Weg?
bearbeiten hinzuzufügen: Ich bin mir bewusst, dass die Karten nicht Thread-sicher sind. Sie sind jedoch nach der Go-Spezifikation unter http://golang.org/ref/spec#For_statements in einer Richtung threadsicher (Suche nach "Wenn Map-Einträge, die noch nicht erreicht wurden, während der Iteration gelöscht werden"). Diese Seite zeigt an, dass der Code, der range
verwendet, sich nicht darum kümmern muss, dass andere Goroutines in die Karte eingefügt oder daraus gelöscht werden. Meine Frage ist, erweitert sich diese Gewinderesistenz auf v
, so dass ich v
zum Lesen nur mit nur for k, v := range m
und keine anderen thread-sicheren Mechanismus bekommen kann? Ich habe einen Testcode erstellt, um zu versuchen, einen App-Absturz zu erzwingen, der beweist, dass er nicht funktioniert, aber sogar anstößigen thread-unsafe-Code laufen lässt (viele goroutines modifizieren den gleichen Map-Wert ohne Locking-Mechanismus) Geh zum Absturz!
Nur ein Kommentar (weniger für OP, die wahrscheinlich weiß es bereits als für andere Leser): http://golang.org/doc/go_faq.html#atomic_maps –