Sobes.tech
Middle

Wat is een mutex, welke typen mutexen bestaan er en hoe gebruik je ze?

sobes.tech AI

Antwoord van AI

De mutex (afgeleid van het Engels MUTual EXclusion) is een primitieve synchronisatie die wordt gebruikt om exclusieve toegang tot een gedeelde bron te garanderen tussen concurrerende goroutines. Het garandeert dat op elk moment slechts één goroutine de mutex kan bezitten en toegang heeft tot de beschermde gegevens.

In Go biedt de sync-package twee hoofdtypen mutexen:

  • sync.Mutex: Standaard mutex. Biedt de methoden Lock() en Unlock(). Als de mutex al vergrendeld is, blokkeert de aanroep van Lock() de huidige goroutine totdat deze wordt vrijgegeven. Unlock() ontgrendelt de mutex.

    var mu sync.Mutex
    var counter int
    
    func increment() {
        mu.Lock() // Blokkeert toegang tot counter
        counter++
        mu.Unlock() // Ontgrendelt toegang
    }
    
  • sync.RWMutex: Mutex voor lezen/schrijven. Staat meerdere goroutines toe om gelijktijdig de beschermde bron te lezen, maar slechts één te schrijven. Biedt de methoden Lock(), Unlock() (voor schrijven), RLock() en RUnlock() (voor lezen).

    var rwMu sync.RWMutex
    var data []int
    
    func readData() {
        rwMu.RLock() // Blokkeert voor lezen
        // Leest data
        fmt.Println(data)
        rwMu.RUnlock() // Ontgrendelt lezen
    }
    
    func writeData(val int) {
        rwMu.Lock() // Blokkeert voor schrijven
        // Schrijft in data
        data = append(data, val)
        rwMu.Unlock() // Ontgrendelt schrijven
    }
    

Het gebruik van mutexen is nodig om race conditions te voorkomen, wanneer meerdere goroutines proberen gelijktijdig dezelfde gegevens te wijzigen, wat tot onvoorspelbare resultaten leidt.

Gebruiksregels:

  1. Roep Lock() aan voordat je toegang krijgt tot de beschermde bron.
  2. Roep Unlock() aan nadat je klaar bent met de toegang. Het wordt aanbevolen om defer mu.Unlock() te gebruiken om de vrijgave te garanderen, zelfs in geval van een panic.
  3. Probeer niet een al vergrendelde mutex te vergrendelen vanuit dezelfde goroutine (kan leiden tot deadlock).
  4. Probeer geen niet-vergrendelde mutex te ontgrendelen.
  5. Gebruik RLock/RUnlock voor leesbewerkingen en Lock/Unlock voor schrijfbewerkingen bij gebruik van RWMutex.
  6. Mutexen mogen niet worden gekopieerd na het eerste gebruik. Geef ze door via referentie of pointer.

Voorbeeld van gebruik van defer:

func safeIncrement() {
    mu.Lock()
    defer mu.Unlock() // Garandeert de vrijgave
    counter++
}