Sobes.tech
Middle

Mutex nədir, hansı növ mutexlər mövcuddur və onları necə istifadə etmək olar?

sobes.tech Süni İntellekt

AI-dan cavab

Muteks (İngiliscə MUTual EXclusion) paylaşılan resursa mübarizə edən gorutinalar arasında müstəsna giriş təmin etmək üçün istifadə olunan sinxronizasiya primitive-dir. O, hər hansı bir zamanda yalnız bir gorutinanın muteksə sahib olmasını və qorunan verilərə çıxışını təmin edir.

Go-da sync paketi iki əsas muteks növü təqdim edir:

  • sync.Mutex: Standart muteks. Lock()Unlock() metodlarını təmin edir. Əgər muteks artıq bloklanıbsa, Lock() çağırışı cari gorutinanı onun azad olunmasına qədər bloklayır. Unlock() muteksi azad edir.

    var mu sync.Mutex
    var counter int
    
    func increment() {
        mu.Lock() // counter-ə giriş bloklanır
        counter++
        mu.Unlock() // giriş azad edilir
    }
    
  • sync.RWMutex: Oxuma/yazma üçün muteks. Eyni zamanda bir çox gorutina qorunan resursu oxuya bilər, lakin yalnız bir gorutina yaza bilər. Lock(), Unlock() (yazma üçün), RLock()RUnlock() (oxuma üçün) metodlarını təmin edir.

    var rwMu sync.RWMutex
    var data []int
    
    func readData() {
        rwMu.RLock() // Oxuma üçün bloklayır
        // data-ya oxuyur
        fmt.Println(data)
        rwMu.RUnlock() // Oxumağı azad edir
    }
    
    func writeData(val int) {
        rwMu.Lock() // Yazma üçün bloklayır
        // data-ya yazır
        data = append(data, val)
        rwMu.Unlock() // Yazmağı azad edir
    }
    

Muteks istifadə etmək zəruridir, çünki o, yarış vəziyyətlərinin (race conditions) qarşısını alır, çoxlu gorutinalar eyni zamanda eyni məlumatları dəyişdirməyə çalışdıqda, nəticələrin proqnozlaşdırılmaması ilə nəticələnir.

İstifadə qaydaları:

  1. Qorunan resursa girişdən əvvəl Lock() çağırın.
  2. Giriş tamamlandıqdan sonra Unlock() çağırın. Panik halında belə, azad etməni təmin etmək üçün defer mu.Unlock() istifadə etmək tövsiyə olunur.
  3. Eyni gorutindən artıq bloklanmış muteksi bloklamağa çalışmayın (bu deadlock-a səbəb ola bilər).
  4. Bloklanmamış muteksi azad etməyə çalışmayın.
  5. RWMutex istifadə edərkən, oxuma əməliyyatları üçün RLock/RUnlock, yazma əməliyyatları üçün isə Lock/Unlock istifadə edin.
  6. Mutekslər ilk istifadədən sonra kopyalanmamalıdır. Onları referens və ya göstərici ilə ötürün.

defer istifadəsinin nümunəsi:

func safeIncrement() {
    mu.Lock()
    defer mu.Unlock() // Azad etməni təmin edir
    counter++
}