Mutex
Mutex ko'plab goroutinelar bir vaqtning o'zida umumiy (shared) xotira manziliga kirishini boshqarish uchun ishlatiladigan vosita hisoblanadi. U sync paketida joylashgan bo'lib, parallel ishlovchi jarayonlar o'rtasida race condition ni oldini olishda muhim rol o'ynaydi.
Tasavvur qiling, sizda bank hisob raqami mavjud. Ayni bir vaqtda quyidagi ikkita operatsiyani bajarmoqchisiz:
- Bankomat orqali pul yechmoqchisiz
- Mobil ilova orqali boshqa kartaga pul o'tkazmoqchisiz
Bu ikkala operatsiya bir vaqtda bajarilsa, har bir operatisya bajarilishidan oldin hisobni tekshiradi va bir xil balans masalan 1000 so'm degan natijani oladi. Natijada:
- Bankomat 1000 so'm yechadi
- Mobil ilova ham 1000 so'm o'tkazadi
- Jami 2000 so'm sarflanadi, lekin hisobda faqat 1000 so'm bor edi!
Bu holat race condition deb ataladi. Ya'ni, bir nechta goroutinelar bir vaqtda bir xil ma'lumot bilan ishlayotgani uchun noto'g'ri natija yuzaga keladi.
Bunday muammoni oldini olish uchun mutexdan foydalaniladi. Ya'ni, har bir operatsiya boshlanishidan avval mutex.Lock()
orqali resursga kirishni qulflaydi, va ish tugagach mutex.Unlock()
orqali qulfni bo'shatadi. Shu orqali bir vaqtda faqat
bitta operatsiya hisob raqam bilan ishlashi mumkin bo'ladi.
Yuqoridagi bank misolni kichik dastur yozib yaxshiroq tushunishga harakat qilamiz.
Bu misolda:
- Bitta bank hisob raqami mavjud (boshlang'ich balans: 1000 so'm)
- Ikki goroutine:
- biri bankomatdan pul yechadi
- biri mobil ilovadan pul o'tkazadi
- Har bir operatsiya hisobni tekshiradi va pulni ayiradi.
Mutexsiz misol:
Natija:
Mobil ilova Pul yechmoqchi: 700 so'm
Mobil ilova O'qilgan balans: 1000
Bankomat Pul yechmoqchi: 800 so'm
Bankomat O'qilgan balans: 1000
Bankomat Shart bajardi: balans >= 800
Bankomat Pul yechildi! Yangi balans: 200
Mobil ilova Shart bajardi: balans >= 700
Mobil ilova Pul yechildi! Yangi balans: 300
Operatsiyalar tugadi. Yakuniy balans: 300
Nima sodir bo'lid?
- Hisobda 1000 so'm bor.
- Ikkita operatsiya bir vaqtda bo'lmoqda:
- Bankomat: 800 so'm yechmoqchi
- Mobil ilova: 700 so'm yechmoqchi
Agar operatsiyalar navbat bilan, xavfsiz tarzda bajarilganida:
- Bankomat 800 so'mni oladi -> Qolgan: 200
- Mobil ilova tekshiradi: 700 > 200 -> mablag' yetmaydi -> pul yechilmasligi kerak edi.
Mobil ilova pulni yechmasligi kerak edi, lekin race condition bo'lganida u yolg'on shartni bajarib yuboradi, chunki mobil ilova balans o'zgarishini bilmaydi.
Mutex bilan misol:
Natija:
Bankomat Pul yechmoqchi: 800 so'm
Bankomat O'qilgan balans: 1000
Bankomat Shart bajardi: balans >= 800
Bankomat Pul yechildi! Yangi balans: 200
Mobil ilova Pul yechmoqchi: 700 so'm
Mobil ilova O'qilgan balans: 200
Mobil ilova Yetarli mablag' yo'q! Balans: 200
Operatsiyalar tugadi. Yakuniy balans: 200
Endi nima bo'ldi?
- mutex orqali har bir goroutine navbat bilan ishlayapti.
- Har biri balance o'zgaruvchisini o'zi yolg'iz o'qiydi va o'zgartiradi shu bilan race conditionni butunlay oldi olinadi.