Sobes.tech
Middle

Was ist der Unterschied zwischen einem Semaphore und einem Mutex?

sobes.tech KI

Antwort von AI

Ein Semaphor ist ein verallgemeinerter Synchronisationsmechanismus, der verwendet wird, um den Zugriff auf begrenzte Ressourcen durch mehrere konkurrierende Threads zu steuern. Es hält einen ganzzahligen Wert, der beim Zugriff auf die Ressource verringert und beim Freigeben erhöht wird. Wenn der Semaphorwert null ist, blockiert der Versuch, ihn zu erlangen, den Thread, bis ein anderer Thread die Ressource freigibt. Es kann verwendet werden, um die Anzahl der gleichzeitig arbeitenden Threads zu begrenzen.

Ein Mutex (Mutual Exclusion) ist ein binärer Semaphor, der sich entweder im blockierten oder im entsperrten Zustand befindet. Es wird verwendet, um kritische Abschnitte des Codes vor gleichzeitigen Zugriffen mehrerer Threads zu schützen. Nur ein Thread kann den Mutex zu einem Zeitpunkt erlangen. Der Thread, der den Mutex erlangt hat, kann nicht von einem anderen Thread unterbrochen werden, der versucht, ihn zu erlangen. Wenn versucht wird, einen blockierten Mutex zu erlangen, wird der Thread bis zu seiner Freigabe blockiert.

Wichtige Unterschiede:

Merkmal Semaphor Mutex
Typ Verallgemeinerter Synchronisationsmechanismus Binärer Semaphor (Spezialfall des Semaphors)
Wert Ganzzahlig (>= 0) Binär (0 oder 1)
Zweck Steuerung des Zugriffs auf Ressourcen, Begrenzung der Threads Schutz kritischer Abschnitte, gegenseitiger Ausschluss
Eigentümer Kann keinen Eigentümer haben Hat immer einen Eigentümer (Thread, der ihn erlangt hat)
Verwendung in iOS DispatchSemaphore Wird häufig durch DispatchQueue.sync oder NSRecursiveLock in bestimmten Szenarien implementiert

Beispiel für die Verwendung eines Mutex zum Schutz eines kritischen Abschnitts:

// Im Kontext von GCD (Grand Central Dispatch)
let serialQueue = DispatchQueue(label: "com.example.criticalSection")

serialQueue.sync {
    // Kritischer Codeabschnitt
    // Nur ein Thread kann hier gleichzeitig sein
}

Beispiel für die Verwendung eines Semaphors zur Begrenzung paralleler Aufgaben:

// Im Kontext von GCD (Grand Central Dispatch)
let semaphore = DispatchSemaphore(value: 3) // Erlaubt 3 parallele Aufgaben

DispatchQueue.global().async {
    semaphore.wait() // Verringert den Wert des Semaphors um 1. Blockiert, wenn der Wert 0 ist.

    // Code der parallelen Aufgabe
    print("Aufgabe läuft")

    Thread.sleep(forTimeInterval: 1) // Arbeitssimulation

    semaphore.signal() // Erhöht den Wert des Semaphors um 1. Entblockt den wartenden Thread, falls vorhanden.
    print("Aufgabe beendet")
}

// Es können mehrere solcher Blöcke gestartet werden. Nur 3 werden gleichzeitig ausgeführt.