sync.Map Deep Dive
sync.Map'ga chuqur nazar
Har safar Mutex bilan qo'lda o'rab qo'yish o'rniga, agar sizga faqat xavfsiz xarita (map) kerak bo'lsa, standart kutubxonada allaqachon tayyor yechim bor: sync.Map. U — bir nechta goroutine bir vaqtda ishlatishi mumkin bo'lgan, ichida o'zining himoyasi ("kalit"i) allaqachon o'rnatilgan xarita.
package main
import (
"fmt"
"sync"
)
func main() {
var m sync.Map
var wg sync.WaitGroup
for i := 0; i < 50; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
m.Store(n, n*n)
}(i)
}
wg.Wait()
v, ok := m.Load(7)
fmt.Println(v, ok)
}Oddiy map[int]int o'rniga sync.Map ishlatilgan, va u odatdagi m[key] = value yoki m[key] sintaksisini QABUL QILMAYDI — buning o'rniga Store(kalit, qiymat) va Load(kalit) metodlari ishlatiladi. Load esa mapdagi kabi ikkita qiymat qaytaradi: qiymatning o'zi va uning haqiqatan mavjudligini bildiruvchi bool.
Muhim savol: nega har doim sync.Map ishlatmaymiz, agar u xavfsiz bo'lsa? Chunki uning ichki tuzilishi ko'p o'qish, kam yozish holatlariga moslashtirilgan (masalan, konfiguratsiya keshini saqlash). Agar sizda ko'p yozish bo'lsa, oddiy map + sync.Mutex odatda tezroq va soddaroq ishlaydi. sync.Mapni "har doim yaxshiroq" emas, balki "aniq bir vaziyat uchun maxsus vosita" deb bilish kerak.
>_ Exercise
sync.Map bilan konkurrent sanoq (counter) yasang.
- •sync.Map ishlatib, 20 ta goroutine "visits" kalitini LoadOrStore/Store orqali oshiring (soddalik uchun mu bilan himoyalangan oddiy int hisoblagichdan sync.Map orqali o'qib-yozing)
- •yakunida m.Load("visits") natijasini chop eting
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
sync.Map — ko'p o'qish/kam yozish holatlari uchun maxsus, tayyor xavfsiz xarita; lekin "o'qib-o'zgartirib-yozish" kabi ketma-ket amallar uchun baribir qo'shimcha sinxronlash (Mutex) kerak bo'lishi mumkin.
NEXT UP
Atomic Operations
$ go run main.go
Kodingizni ishga tushiring