Es ist nicht möglich, dass zwei (oder mehr) Threads gleichzeitig eine Sperre erhalten. Es gibt zum Beispiel einige Arten von Synchronisationsmethoden:
Aktives Warten - Drehsperre
Pseudocode:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG ist ein Beispiel für eine atomare Operation (in der x86-Architektur vorhanden), bei der zuerst ein neuer Wert für eine "Sperr" -Variable festgelegt und dann ein alter Wert zurückgegeben wird. Atomic bedeutet, dass es nicht unterbrochen werden kann - im obigen Beispiel zwischen dem Setzen eines neuen Werts und dem Zurückgeben eines alten. Atomdeterministisches Ergebnis, egal was passiert.
2. Your code
3. lock = 0; - exit protocol
Wenn lock gleich 0 ist, kann ein anderer Thread in den kritischen Bereich eintreten - während die Schleife endet.
Thread-Suspending - zum Beispiel Zählen von Semaphoren
Es gibt zwei atomare Operationen .Wait()
und .Signal()
wir haben eine Integer-Variable, die wir aufrufen können int currentValue
.
Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;
Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;
Das Lösen von Problemen mit kritischen Abschnitten ist jetzt ganz einfach:
Pseudocode:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
Normalerweise sollte Ihre Programmierthread-API Ihnen die Möglichkeit geben, maximal gleichzeitige Threads im semaphorenkritischen Abschnitt anzugeben. Offensichtlich gibt es in Multithread-Systemen (Mutex, Monitore, Binärsemaphore usw.) mehr Arten der Synchronisation, aber sie basieren auf den obigen Vorstellungen. Man könnte argumentieren, dass Methoden, die Thread-Suspending verwenden, dem aktiven Warten vorgezogen werden sollten (damit CPU nicht verschwendet wird) - es ist nicht immer die Wahrheit. Wenn der Thread angehalten wird, findet ein teurer Vorgang statt, der als Kontextwechsel bezeichnet wird. Es ist jedoch sinnvoll, wenn die Wartezeit kurz ist (Anzahl der Threads ~ Anzahl der Kerne).