Sobes.tech
Middle+

Xəritədə eyni vaxtda yazma zamanı səhvlərdən necə qorunmaq olar?

sobes.tech Süni İntellekt

AI-dan cavab

Golang-da map üzərində eyni vaxtda yazma zamanı baş verə biləcək səhvlərdən qorunmaq üçün, standart olaraq çox iş parçacığı təhlükəsiz olmayan aşağıdakı mexanizmlər istifadə olunur:

  • sync.Mutex: map-i yazmadan əvvəl kilidləyir və sonra açır.

    import "sync"
    
    type SafeMap struct {
        mu sync.Mutex
        data map[string]int
    }
    
    func NewSafeMap() *SafeMap {
        return &SafeMap{
            data: make(map[string]int),
        }
    }
    
    func (sm *SafeMap) Set(key string, value int) {
        sm.mu.Lock()
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMap) Get(key string) (int, bool) {
        sm.mu.Lock()
        defer sm.mu.Unlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.RWMutex: Bir neçə goroutine-un eyni zamanda map-i oxumağa imkan verir, lakin eyni vaxtda oxuma və ya yazma zamanı kilidlər.

    import "sync"
    
    type SafeMapRWMutex struct {
        mu sync.RWMutex
        data map[string]int
    }
    
    func NewSafeMapRWMutex() *SafeMapRWMutex {
        return &SafeMapRWMutex{
            data: make(map[string]int),
        }
    }
    
    func (sm *SafeMapRWMutex) Set(key string, value int) {
        sm.mu.Lock() // Yazma kilidi
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Oxuma kilidi
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Xüsusi çox iş parçacığı təhlükəsiz tipi, daha çox istifadə olunan senarilərdə, yəni açarların nisbətən sabit olduğu və yazma əməliyyatlarının nadir olduğu və ya çox sayda goroutine müxtəlif açar dəstləri üçün oxuyub-yazdığı hallarda optimallaşdırılmışdır.

    import "sync"
    
    var safeMap sync.Map // Deklarasiya
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Yazma
        if val, ok := safeMap.Load("key1"); ok { // Oxuma
            // Val istifadə et
        }
        safeMap.Delete("key1") // Silmə
    }
    

Yanaşmaların müqayisəsi:

Mexanizm Üstünlüklər Dezavantajlar Tətbiq
sync.Mutex İstifadəsi sadə Yazma zamanı bütün əməliyyatları bloklayır Sadə hallarda, yəni çoxluq yüksək olmayan və ya oxuma/yazma nisbəti bərabər olan hallarda.
sync.RWMutex Paralel oxumağa imkan verir sync.Mutex-dən daha mürəkkəb. Yazma oxuma və digər yazma əməliyyatlarını bloklayır. Çox oxuma və az yazma halları üçün.
sync.Map Bəzi hallarda optimallaşdırılmışdır API məhduddur. Tamamilə təsadüfi girişdə Mutex-dən daha yavaş ola bilər. Sabit və ya disjunkt açar dəstləri olan hallarda, müxtəlif goroutine-lər üçün.

Xüsusi bir yanaşmanın seçimi, map-ə çox iş parçacığı ilə girişin xarakterinə bağlıdır. Ümumi hallarda, adətən sync.Mutex və ya sync.RWMutex kifayət edir. Xüsusi hallarda isə, sync.Map daha yaxşı performans göstərə bilər.