Go'da haritalar (map), varsayılan olarak thread-safe (çoklu iş parçacığına güvenli) değildir. Eğer birden fazla goroutine aynı anda bir haritaya yazıyorsa veya okuma yapıyorsa, senkronizasyon olmadan bir veri yarışı durumu (data race) meydana gelir ve bu da fatal error: concurrent map read and map write hatasına veya veri bozulmasına yol açar.
Thread-safe bir şekilde haritalarla çalışmak için şunları yapmak gerekir:
sync.Mutex veya sync.RWMutex temel yapı taşlarını kullanmak.sync.Map paketini kullanmak.var mu sync.RWMutex m := make(map[string]int) // Yazma mu.Lock() m["key"] = 1 mu.Unlock() // Okuma mu.RLock() v := m["key"] mu.RUnlock() // Veya sync.Map var sm sync.Map sm.Store("key", 1) v, _ := sm.Load("key")
Go'daki bir harita üzerinde farklı goroutine'lerden aynı anda okuma ve yazma neden bu kadar tehlikeli, eğer harita yerleşik bir türse?
Cevap: Go'da yerleşik harita türü senkronizasyon sağlamaz. Birden fazla goroutine tarafından haritaya eş zamanlı erişim, sadece hatalı değerler değil, programın çökmesine de neden olabilir. Hatta kesişen anahtarlar olmasa bile eş zamanlı okuma ve yazma yapmak fatal hatalara yol açabilir. Bu durum, bazı diğer dillerde koleksiyonların rekabetçi erişimlere "toleranslı" olduğu durumdan farklıdır.
Hikaye
Gerçek bir projede, bir geliştirici veri önbelleklemesi için küresel bir harita kullandı. Servis testlerde stabil çalıştı, fakat yük testlerinde ve prodüksiyonda fatal error: concurrent map read and map write hatasıyla çökmeye başladı. Bunun nedeni, Mutex kullanılmadan farklı http isteklerinden haritaya paralel erişimdi.
Hikaye
Go'daki bir web uygulamasında bir programcı performansı artırmak istedi ve klasik bir haritayı bağlantı havuzu olarak kullandı, çok iş parçacıklı olmanın çerçeve tarafından sağlandığını varsayarak. Trafikteki ani bir artışta servis, açık bir neden olmadan çökme yaşadı: veri yarışı nedeniyle haritadaki veriler bozuluyordu ve panikler oluşuyordu.
Hikaye
Go iç hizmetinde bir uygulama, sadece yazma işlemi olduğu varsayımıyla "anlık" istatistik toplamak için harita kullandı. Aslında, başka bir kod parçası, raporlar oluşturmak için ara sıra veri sorguluyordu ve bu durum, yalnızca günde bir kez zor yakalanan çöküşlere yol açıyordu - istatistik devreye girdiğinde. Analiz, okuma ve yazmaların herhangi bir kilit olmadan örtüştüğünü gösterdi.