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.