Sobes.tech
Middle+

Jak działa mutex w korutynach?

sobes.tech AI

Odpowiedź od AI

Mutex (Mutual Exclusion) w korutynach zapewnia mechanizm wzajemnego wykluczania do ochrony wspólnych zasobów przed jednoczesnym dostępem przez wiele korutyn.

Zasada działania:

  1. Przyjęcie mutexa: Korutyna, która chce uzyskać dostęp do chronionego zasobu, wywołuje metodę lock().
  2. Blokada: Jeśli mutex jest wolny, korutyna go przejmuje bez blokowania i kontynuuje wykonywanie. Jeśli mutex jest zajęty przez inną korutynę, wywołująca korutyna jest zawieszana do czasu zwolnienia mutexa.
  3. Uwolnienie mutexa: Po zakończeniu pracy z chronionym zasobem, korutyna wywołuje metodę unlock(), aby zwolnić mutex.

Kluczowe cechy w korutynach:

  • lock() nieblokujące (przy przejęciu wolnego mutexa): W przeciwieństwie do tradycyjnych wątków, gdzie lock() może blokować cały wątek, w korutynach, jeśli mutex jest wolny, przejęcie odbywa się bez blokowania.
  • Zawieszenie korutyny (gdy mutex jest zajęty): Jeśli mutex jest zajęty, wywołująca korutyna nie blokuje wątku, lecz zawiesza się do czasu zwolnienia. To zwalnia wątek do wykonywania innych korutyn.
  • Funkcja rozszerzenia withLock: Wygodny sposób korzystania z mutexa, który automatycznie go przejmuje i zwalnia, nawet jeśli w bloku wystąpi wyjątek.

Przykład użycia:

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex

val mutex = Mutex()
var counter = 0

suspend fun incrementCounter() {
    mutex.withLock {
        // Sekcja krytyczna - chroniony zasób
        counter++
        delay(10) // Symulacja pracy
        println("Counter: $counter")
    } // Mutex jest automatycznie zwalniany tutaj
}

fun main() = runBlocking {
    repeat(100) {
        launch {
            incrementCounter()
        }
    }
    delay(1000)
}

W tym przykładzie incrementCounter jest sekcją krytyczną, która modyfikuje wspólny zasób counter. Mutex gwarantuje, że tylko jedna korutyna na raz ma dostęp do tej sekcji, zapobiegając warunkom wyścigu. Użycie withLock upraszcza zarządzanie mutexem.