Dekker-Algorithmus
Der Dekker-Algorithmus ist die älteste bekannte vollständige Lösung[1] des Problems, den wechselseitigen Ausschluss (Mutex) in der dezentralen Steuerung von Prozessen (Prozesssynchronisation) zu gewährleisten. Er vermeidet gegenseitiges Blockieren (Deadlock) und gewährleistet, dass stets genau ein Prozess in einen kritischen Abschnitt gelangen kann (Sequentialisierung). Der Algorithmus wurde 1965 von dem niederländischen Mathematiker Theodorus Dekker formuliert.[2] In der hier beschriebenen Form kann er aber nur zwei Prozesse wechselseitig ausschließen.
Schema
Der Algorithmus kann mit folgendem C-Code schematisch beschrieben werden:
// Willensbekundungen, den kritischen Abschnitt betreten zu wollen
volatile boolean wants_to_enter[2] = { false, false };
// letzter Thread, bei Konflikten der jeweils wartende Thread
volatile int last_thread = 1; // Initialisierung kann mit 0 oder 1 erfolgen
| |
// Thread 0
wants_to_enter[0] = true;
while (wants_to_enter[1]) {
if (last_thread == 0) { //°
wants_to_enter[0] = false;
while (last_thread == 0)
;
wants_to_enter[0] = true;
}
}
// hier kritischen Abschnitt einfügen
last_thread = 0;
wants_to_enter[0] = false;
|
// Thread 1
wants_to_enter[1] = true;
while (wants_to_enter[0]) {
if (last_thread == 1) { //°
wants_to_enter[1] = false;
while (last_thread == 1)
;
wants_to_enter[1] = true;
}
}
// hier kritischen Abschnitt einfügen
last_thread = 1;
wants_to_enter[1] = false;
|
// °) Im Fall, dass
// * ein Thread den kritischen Abschnitt betreten möchte,
// * der andere Thread diesen aber auch betreten möchte oder betreten hat,
// * lässt der Thread, der das letzte Mal zum Zuge gekommen ist
// - dem anderen Thread die Vorfahrt und setzt seinen Eintrittswunsch so lange zurück
// - bis der andere fertig ist
// * pocht der Thread, der das letzte Mal nicht zum Zuge gekommen ist
// - auf die Erteilung der Semaphore
// * Neben dem Ausbalancieren der Eintrittschancen ist zusätzlich geklärt
// - wer zurückzutreten und zu warten hat und damit die Richtung der Signalisierung
| |
Funktionsweise
Der Dekker-Algorithmus für zwei Prozesse arbeitet mit drei Variablen.
Zwei geben den Wunsch des Betretens des kritischen Abschnitts an wants_to_enter, eine den letzten benutzenden Thread last_thread.
Der letzte benutzende Thread trägt sich noch am Ende des kritischen Abschnitts als letzten benutzenden Thread ein und stellt sich damit bei einem Konflikt
hinten an.
Für ihn sieht beim nächsten Aufruf, wenn der andere noch nicht zum Zuge gekommen ist, das Eintreten so aus:
wants_to_enter[me] = true;
while (wants_to_enter[other]) {
wants_to_enter[me] = false; // Rückstellung
while (last_thread == me) // Warte, bis der andere durch ist °)
;
wants_to_enter[me] = true;
}
...
wants_to_enter[me] = false; // Löst °°)
Für den anderen Thread (man beachte, das me und other jeweils dem other und me des anderen Threads entsprechen):
wants_to_enter[me] = true;
while (wants_to_enter[other]) // Poche auf meine Anforderung, °°)
;
...
last_thread = me; // Löst °)
Bedeutung
Im Gegensatz zu früher gefundenen Lösungen zur dezentralen Steuerung arbeitet der Dekker-Algorithmus aufgrund der Variable last_thread auch dann korrekt, wenn das Scheduling abwechselnd zwischen beiden Prozessen hin und her springt. Eine generalisierte Lösung zur Synchronisation von N Prozessen wurde ebenfalls noch 1965 von Edsger W. Dijkstra gefunden.[3]
Eine Vereinfachung findet sich im ebenfalls korrekt arbeitenden Peterson-Algorithmus, der jedoch erst 16 Jahre später entwickelt wurde. Der Nachteil der dezentralen Steuerung bleibt bestehen: Wartende Prozesse geben den Prozessor nicht ab, sondern beanspruchen ihn durch Busy waiting.
Einzelnachweise
- ↑ E. W. Dijkstra: "Cooperating sequential processes", Technological University, Eindhoven, The Netherlands, September 1965
- ↑ Joe Duffy: "Concurrent Programming on Windows", Addison-Wesley Professional, 2008
- ↑ E. W. Dijkstra: "Solution of a Problem in Concurrent Programming Control", Communications of the ACM, Volume 8 Issue 9, 1965, S. 569
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.