Channel'lar goroutine'lar o'rtasidagi aloqa uchun naqadar zo'r ekanini ko'rdik.
Lekin aloqa kerak bo'lmasa-chi? Nizolarning oldini olish uchun o'zgaruvchiga bir vaqtda faqat bitta goroutine murojaat qila olishini ta'minlashni xohlasak-chi?
Bu tushuncha o'zaro istisno (mutual exclusion) deb ataladi, uni ta'minlovchi ma'lumotlar tuzilmasining odatiy nomi esa mutex.
Go standart kutubxonasi o'zaro istisnoni sync.Mutex va uning ikki metodi bilan taqdim etadi:
LockUnlockKod blokini o'zaro istisno rejimida bajariladigan qilib belgilash uchun uni Lock va Unlock chaqiruvlari bilan o'rab olamiz, bu Inc metodida ko'rsatilgan.
Mutex'ning qulfdan chiqarilishini kafolatlash uchun
deferdan ham foydalanishimiz mumkin, buValuemetodidagidek.
Yechimni kodning pastki qismidagi
Topshiriqlarbo'limiga yozing, so'ng Submit tugmasini bosing. Mavzu mustahkam o'zlashishi uchun ikkala topshiriqni ham bajaring.
SafeCounter uchun Dec(key string) metodini yozing: berilgan kalit uchun hisoblagichni bittaga kamaytirsin. U ham Inc kabi bir vaqtda ishlatish uchun xavfsiz (mutex bilan) bo'lishi kerak.
SafeCounter uchun Jami() int metodini yozing: barcha kalitlar bo'yicha qiymatlar yig'indisini qaytarsin. Mapni o'qishda ham mutex bilan qulflang (defer c.mu.Unlock()).