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()və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()və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ı:
- Qorunan resursa girişdən əvvəl
Lock()çağırın. - Giriş tamamlandıqdan sonra
Unlock()çağırın. Panik halında belə, azad etməni təmin etmək üçündefer mu.Unlock()istifadə etmək tövsiyə olunur. - Eyni gorutindən artıq bloklanmış muteksi bloklamağa çalışmayın (bu deadlock-a səbəb ola bilər).
- Bloklanmamış muteksi azad etməyə çalışmayın.
RWMutexistifadə edərkən, oxuma əməliyyatları üçünRLock/RUnlock, yazma əməliyyatları üçün isəLock/Unlockistifadə edin.- 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++
}