Sobes.tech
Middle

Mutex nima, qanday turlar mutexlar mavjud va ularni qanday ishlatish mumkin?

sobes.tech AI

AIdan javob

Muteks (ing. MUTual EXclusion) — bu sinxronizatsiya uchun ishlatiladigan primitive bo‘lib, u raqobatlashayotgan gorutinlar o‘rtasida umumiy resursga eksklyuziv kirishni ta’minlaydi. U har qanday vaqtda faqat bitta gorutin muteksga egalik qilishi va himoyalangan ma’lumotlarga murojaat qilishi mumkinligini kafolatlaydi.

Go tilida sync paketi ikki asosiy muteks turini taqdim etadi:

  • sync.Mutex: Standart muteks. Lock() va Unlock() metodlarini taqdim etadi. Agar muteks allaqachon bloklangan bo‘lsa, Lock() chaqiruvi joriy gorutinani bloklab, uni bo‘shatguniga qadar kutadi. Unlock() muteksni ochadi.

    var mu sync.Mutex
    var counter int
    
    func increment() {
        mu.Lock() // counterga kirishni bloklaydi
        counter++
        mu.Unlock() // kirishni ochadi
    }
    
  • sync.RWMutex: O‘qish/yozish uchun muteks. Bir vaqtning o‘zida ko‘p gorutinlar himoyalangan resursni o‘qishi mumkin, lekin faqat bittasi yozishi mumkin. Lock(), Unlock() (yozish uchun), RLock() va RUnlock() (o‘qish uchun) metodlarini taqdim etadi.

    var rwMu sync.RWMutex
    var data []int
    
    func readData() {
        rwMu.RLock() // O‘qish uchun bloklaydi
        // data ni o‘qish
        fmt.Println(data)
        rwMu.RUnlock() // O‘qishni ochadi
    }
    
    func writeData(val int) {
        rwMu.Lock() // Yozish uchun bloklaydi
        // data ga yozish
        data = append(data, val)
        rwMu.Unlock() // Yozishni ochadi
    }
    

Mutekslar foydalanish uchun zarur, chunki ular raqobat shartlarini (race conditions) oldini oladi, ya’ni bir nechta gorutinlar bir vaqtning o‘zida bir xil ma’lumotlarni o‘zgartirishga urinishadi va bu noaniq natijalarga olib keladi.

Foydalanish qoidalari:

  1. Himoyalangan resursga kirishdan oldin Lock() chaqiring.
  2. Kirishni tugatgandan so‘ng Unlock() chaqiring. Panik holatida ham blokirovkani ta’minlash uchun defer mu.Unlock() ishlatish tavsiya etiladi.
  3. O‘sha gorutinadan o‘zida allaqachon bloklangan muteksni bloklamaslikka harakat qiling (bu deadlockga olib kelishi mumkin).
  4. Bloklanmagan muteksni ochishga harakat qilmang.
  5. RWMutex ishlatishda, o‘qish operatsiyalari uchun RLock/RUnlock, yozish uchun Lock/Unlock ishlating.
  6. Mutekslar birinchi foydalanishdan keyin nusxa ko‘chirilmasligi kerak. Ularni referens yoki ko‘rsatkich orqali uzatish tavsiya etiladi.

deferdan foydalanish misoli:

func safeIncrement() {
    mu.Lock()
    defer mu.Unlock() // Blokdan chiqarishni kafolatlaydi
    counter++
}