Mis on mutex, millised mutexi tüübid on olemas ja kuidas neid kasutada?
sobes.tech AI
Vastus AI-lt
Muteks (inglise keelest MUTual EXclusion) on sünkronsis primitives, mida kasutatakse jagatud ressursi erandliku juurdepääsu tagamiseks konkurentsivõimeliste gorutinide vahel. See tagab, et iga hetk võib ainult üks gorutin omada muteksi ja vastavalt sellele pääseda kaitstud andmetele.
Go paketis sync on kaks peamist muteksi tüüpi:
-
sync.Mutex: Standardne muteks. Pakub meetodeidLock()jaUnlock(). Kui muteks on juba lukustatud, blokeeribLock()jooksva gorutina kuni muteks vabastatakse.Unlock()vabastab muteksi.var mu sync.Mutex var counter int func increment() { mu.Lock() // Lukustab juurdepääsu counterile counter++ mu.Unlock() // Vabastab juurdepääsu } -
sync.RWMutex: Lugemis-/kirjutusmuteks. Lubab mitmel gorutinil samaaegselt lugeda kaitstud ressurssi, kuid ainult ühe kirjutada. Pakub meetodeidLock(),Unlock()(kirjutamiseks),RLock()jaRUnlock()(lugemiseks).var rwMu sync.RWMutex var data []int func readData() { rwMu.RLock() // Lukustab lugemiseks // Loeb data fmt.Println(data) rwMu.RUnlock() // Vabastab lugemise } func writeData(val int) { rwMu.Lock() // Lukustab kirjutamiseks // Kirjutab data data = append(data, val) rwMu.Unlock() // Vabastab kirjutamise }
Muteksi kasutamine on vajalik, et vältida võistlusolukordi (race conditions), kui mitu gorutinit üritavad samaaegselt muuta samu andmeid, mis võib viia ettearvamatute tulemusteni.
Kasutusreeglid:
- Kutsuge
Lock()enne kaitstud ressursile juurdepääsu. - Kutsuge
Unlock()pärast juurdepääsu lõppu. Soovitatav on kasutadadefer mu.Unlock(), et tagada vabastamine isegi paanikase olukorra korral. - Ära püüa lukustada juba lukustatud muteksi samast gorutinas (see võib põhjustada deadlocki).
- Ära püüa vabastada lukustamata muteksi.
- Kui kasutate
RWMutex, kasutageRLock/RUnlocklugemiseks jaLock/Unlockkirjutamiseks. - Muteksi ei tohi pärast esimest kasutamist kopeerida. Neid edastatakse viite või näitaja kaudu.
Näide defer kasutamisest:
func safeIncrement() {
mu.Lock()
defer mu.Unlock() // Garantii vabastamisele
counter++
}