Go'da map varsayılan olarak thread-safe (iş parçacığı güvenli) bir veri yapısı değildir. Farklı goroutinlerden aynı anda haritaya yazma veya değiştirmenin, "concurrent map writes" türünde yarışmalar ve paniklere neden olduğu görülmektedir. Haritayı korumak için genellikle sync.Mutex, sync.RWMutex veya standart kütüphaneden özel bir tip olan sync.Map kullanılır, bu da güvenli atomik işlemler gerçekleştirir.
Haritadan eleman silmek için delete(map, key) kullanılır, ancak harita üzerinde (range ile) yineleme yaparken bazı noktalar dikkate alınmalıdır:
Thread-safe biçimde harita ile çalışma örneği:
type SafeMap struct { mu sync.RWMutex m map[string]int } func (s *SafeMap) Load(key string) (int, bool) { s.mu.RLock() v, ok := s.m[key] s.mu.RUnlock() return v, ok } func (s *SafeMap) Store(key string, value int) { s.mu.Lock() s.m[key] = value s.mu.Unlock() }
Soru: Haritadan elemanları yineleme sırasında güvenli bir şekilde silebilir miyiz?
Cevap: Evet, yalnızca mevcut yinelemeden çıkan anahtarı silmek koşuluyla. Ancak, bu esnada diğer goroutinlerden haritayı değiştirmek yasaktır; bu bir yarış durumu oluşturur.
m := map[string]int{"a": 1, "b": 2, "c": 3} for k := range m { delete(m, k) // güvenli! (eğer yalnızca bu goroutine içinde yapıyorsak) }
Hikaye
Bir izleme hizmeti, harita üzerinden istatistik tutuyordu ve hemen birden fazla goroutinden güncelleniyordu (metrik sayıcıları). Zirve anında "concurrent map writes" hataları oluştu, hizmet kapanıyor ve veriler kayboluyordu. Çözüm: mutex eklemek veya standart harita yerine sync.Map kullanmak.
Hikaye
Veri göçü sürecinde, biri çok büyük bir haritanın temizlenmesini hızlandırmak için paralel gorutinitler kullanmaya karar verdi, her biri kendi anahtar grubunu yineleme ile silmeye çalışıyordu. Sonuç olarak sürekli veri yarışı ve tahmin edilemeyen çöküşler oldu. Göç tamamlandıktan sonra, ya sırayla temizlemeye geri dönmek veya yineleme süresince erişimi bloke etmek gerekti.
Hikaye
Bir geliştirici, harita üzerinde yineleme yaparken aynı haritaya yeni veriler ekliyordu (örneğin, graf için komşu düğümlerin listesini oluştururken). Yeni anahtarların mevcut yinelemede göz ardı edilebileceğini fark etti, bu da grafın tamamlanmamış işlenmesine yol açtı. Hata, sadece nadir durumların tam test edilmesi sırasında keşfedildi. Düzeltme sonrası algoritma, eklemeler için ayrı bir kuyruk kullanılarak yeniden yazıldı.