Middle+
Hogyan működik egy mutex a korutinokban?
sobes.tech MI
Válasz az MI-től
A mutex (Mutual Exclusion) a coroutine-okban egy kölcsönös kizárási mechanizmust biztosít, hogy megvédje a közös erőforrásokat az egyidejű hozzáféréstől több coroutine által.
Működési elv:
- A mutex megszerzése: Az a coroutine, amely hozzáférést szeretne szerezni a védett erőforráshoz, meghívja a
lock()metódust. - Zárolás: Ha a mutex szabad, a coroutine megszerzi anélkül, hogy blokkolná, és folytatja a végrehajtást. Ha a mutex másik coroutine által foglalt, a hívó coroutine szünetel, amíg a mutex ki nem szabadul.
- A mutex felszabadítása: A védett erőforrással végzett munka befejezése után a coroutine meghívja az
unlock()metódust, hogy felszabadítsa a mutexet.
Fő jellemzők coroutine-okban:
lock()nem blokkoló (amikor szabad mutexet szerez): Ellentétben a hagyományos szálakkal, ahol alock()blokkolhatja az egész szálat, coroutine-okban, ha a mutex szabad, a megszerzése nem blokkolódik.- A coroutine felfüggesztése (foglalt mutex esetén): Ha a mutex foglalt, a hívó coroutine nem blokkolja a szálat, hanem felfüggesztődik addig, amíg ki nem szabadul. Ez lehetővé teszi, hogy más coroutine-ok fussanak.
withLockkiterjesztési függvény: Kényelmes módja a mutex használatának, amely automatikusan megszerzi és felszabadítja, még akkor is, ha kivétel történik a blokkban.
Használati példa:
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
val mutex = Mutex()
var counter = 0
suspend fun incrementCounter() {
mutex.withLock {
// Kritikus szakasz - védett erőforrás
counter++
delay(10) // Munka szimuláció
println("Counter: $counter")
} // A mutex itt automatikusan felszabadul
}
fun main() = runBlocking {
repeat(100) {
launch {
incrementCounter()
}
}
delay(1000)
}
Ebben a példában az incrementCounter egy kritikus szakasz, amely módosítja a megosztott counter erőforrást. A mutex biztosítja, hogy egyszerre csak egy coroutine férjen hozzá ehhez a szakaszhoz, elkerülve a versenyhelyzeteket. A withLock használata egyszerűsíti a mutex kezelését.