Der Algorithmus von Dekker

Der Algorithmus von Dekker ist die erste bekannte richtige Lösung des gegenseitigen Ausschluss-Problems in der gleichzeitigen Programmierung. Die Lösung wird dem holländischen Mathematiker Th zugeschrieben. J. Dekker durch Edsger W. Dijkstra in seinem Manuskript auf zusammenarbeitenden folgenden Prozessen. Es erlaubt zwei Fäden, eine Quelle des einzelnen Gebrauches ohne Konflikt mit nur das geteilte Gedächtnis für die Kommunikation zu teilen.

Es vermeidet den strengen Wechsel eines naiven Umdrehung nehmenden Algorithmus, und war einer der ersten gegenseitigen zu erfindenden Ausschluss-Algorithmen.

Einführung

Wenn zwei Prozesse versuchen, in eine kritische Abteilung zur gleichen Zeit einzugehen, wird der Algorithmus nur einen Prozess in, gestützt erlauben, auf wessen Umdrehung es ist. Wenn ein Prozess bereits in der kritischen Abteilung ist, wird der andere Prozess beschäftigt auf den ersten Prozess warten, um abzugehen. Das wird durch den Gebrauch von zwei Fahnen, Fahne [0] und Fahne [1] getan, die eine Absicht anzeigen, in die kritische Abteilung und eine Umdrehungsvariable einzugehen, die anzeigt, wer Vorrang zwischen den zwei Prozessen hat.

Pseudocode

</Zentrum>

Prozesse zeigen eine Absicht an, in die kritische Abteilung einzugehen, die durch den Außen-während Schleife geprüft wird. Wenn der andere Prozess Absicht nicht beflaggt hat, kann in die kritische Abteilung sicher ohne Rücksicht auf die aktuelle Umdrehung eingegangen werden. Gegenseitiger Ausschluss wird noch versichert, weil kein Prozess kritisch vor dem Setzen ihrer Fahne werden kann (Andeutung, dass mindestens ein Prozess während Schleife hereingehen wird). Das versichert auch Fortschritt, weil das Warten auf einem Prozess nicht vorkommen wird, der Absicht zurückgezogen hat, kritisch zu werden. Wechselweise, wenn die Variable des anderen Prozesses gesetzt wurde, während in Schleife eingegangen wird und die Umdrehungsvariable gründen wird, wem erlaubt wird, kritisch zu werden. Prozesse ohne Vorrang werden ihre Absicht zurückziehen, in die kritische Abteilung einzugehen, bis sie wieder (das innere während Schleife) vordringlich behandelt werden. Prozesse mit dem Vorrang werden von brechen, während Schleife und in ihre kritische Abteilung eingeht.

Der Algorithmus von Dekker versichert gegenseitigen Ausschluss, Freiheit vom toten Punkt und Freiheit von Verhungern. Lassen Sie uns sehen, warum das letzte Eigentum hält. Nehmen Sie an, dass p0 innerhalb "während Fahne [1]" Schleife für immer durchstochen wird. Es gibt Freiheit vom toten Punkt, so schließlich wird p1 zu seiner kritischen Abteilung weitergehen und Umdrehung = 0 setzen (und der Wert der Umdrehung wird unverändert nicht weniger als p0 bleiben schreitet nicht fort). Schließlich wird p0 aus dem inneren brechen, "während Umdrehung  0" Schleife (wenn es jemals darauf durchstochen wurde). Danach wird es Fahne [0] setzen: = wahr und lassen sich zum Warten für die Fahne [1] nieder, um falsch zu werden (da sich = 0 drehen, wird es die Handlungen in während Schleife nie tun). Das nächste Mal p1 versucht, in seine kritische Abteilung einzugehen, es wird gezwungen, die Handlungen in sein "während Fahne [0]" Schleife durchzuführen. Insbesondere es wird schließlich Fahne [1] = falsch setzen und in stecken bleiben, "während Umdrehung  1" Schleife (da Umdrehung 0 bleibt). Das nächste Mal kontrolliert Pässe zu p0, es wird abgehen, "während Fahne [1]" Schleife und in seine kritische Abteilung eingeht.

Wenn der Algorithmus durch das Durchführen der Handlungen in "während Fahne [1]" Schleife modifiziert wurde, ohne wenn Umdrehung = 0 zu überprüfen, dann gibt es eine Möglichkeit des Verhungerns. So sind alle Schritte im Algorithmus notwendig.

Bemerken

Ein Vorteil dieses Algorithmus besteht darin, dass er speziellen Test-Und-Satz nicht verlangt (atomar, las/modifizierte/schrieb) Instruktionen, und ist deshalb zwischen Sprachen und Maschinenarchitekturen hoch tragbar. Ein Nachteil ist, dass es auf zwei Prozesse beschränkt wird und vom beschäftigten Warten statt der Prozess-Suspendierung Gebrauch macht. (Der Gebrauch des beschäftigten Wartens weist darauf hin, dass Prozesse ein Minimum der Zeit innerhalb der kritischen Abteilung ausgeben sollten.)

Moderne Betriebssysteme stellen gegenseitige Ausschluss-Primitive zur Verfügung, die allgemeiner und flexibel sind als der Algorithmus von Dekker. Jedoch, ohne wirklichen Streit zwischen den zwei Prozessen, dem Zugang und Ausgang von der kritischen Abteilung ist äußerst effizient, wenn der Algorithmus von Dekker verwendet wird.

Viele moderne Zentraleinheiten führen ihre Instruktionen in in Unordnung Mode durch; sogar Speicherzugänge können wiederbestellt werden (sieh Gedächtnis bestellen). Dieser Algorithmus wird an SMP Maschinen nicht arbeiten, die mit diesen Zentraleinheiten ohne den Gebrauch von Speicherbarrieren ausgestattet sind.

Zusätzlich können viele Optimierungsbearbeiter Transformationen durchführen, die diesen Algorithmus veranlassen werden, unabhängig von der Plattform zu scheitern. Auf vielen Sprachen ist es für einen Bearbeiter gesetzlich zu entdecken, dass auf die Fahne-Variable-Fahne [0] und Fahne [1] in der Schleife nie zugegriffen wird. Es kann dann das Schreiben jenen Variablen von der Schleife mit einem Prozess genannt die Codebewegung der Schleife-invariant entfernen. Es würde auch für viele Bearbeiter möglich sein zu entdecken, dass die Umdrehungsvariable durch die innere Schleife nie modifiziert wird, und führen Sie eine ähnliche Transformation durch, auf eine potenzielle unendliche Schleife hinauslaufend. Wenn jede dieser Transformationen durchgeführt wird, wird der Algorithmus unabhängig von der Architektur scheitern.

Um dieses Problem zu erleichtern, sollten flüchtige Variablen als modifizierbar außerhalb des Spielraums des zurzeit durchführenden Zusammenhangs gekennzeichnet werden. Zum Beispiel, in C# oder Java, würde man diese Variablen als 'flüchtig' kommentieren. Bemerken Sie jedoch, dass der C/C ++ "flüchtiges" Attribut nur versichert, dass der Bearbeiter Code mit der richtigen Einrichtung erzeugt; es schließt die notwendigen Speicherbarrieren für die Garantie um Ausführung dieses Codes nicht ein. C ++ können 11 Atomvariablen verwendet werden, um die passenden Einrichtungsvoraussetzungen — standardmäßig zu versichern, Operationen auf Atomvariablen entsprechen folgend so, wenn die Fahne und Umdrehungsvariablen atomar sind, wird eine naive Durchführung gerade "arbeiten". Wechselweise kann Einrichtung durch den ausführlichen Gebrauch von getrennten Zäunen, mit der Last und den Lager-Operationen mit einer entspannten Einrichtung versichert werden.

Kommentare

Siehe auch

  • Eisenberg &amp; Algorithmus von McGuire
  • Der Algorithmus von Peterson
  • Der Backalgorithmus von Lamport
  • Der Algorithmus von Szymanski
  • Semaphore

Das Fort von Sutter / Gegenseitiger Ausschluss
Impressum & Datenschutz