Prozesssynchronisierung ist eine Technologie, die das Problem des gleichzeitigen Zugriffs auf gemeinsam genutzte Daten löst, der zu Dateninkonsistenzen führen kann. Kollaborierende Prozesse beziehen sich auf Prozesse, die andere Prozesse beeinflussen oder von anderen Prozessen beeinflusst werden können, was zu inkonsistenten Prozessdaten führt. Daher ist eine Prozesssynchronisierung erforderlich, um die Datenkonsistenz sicherzustellen.
Problem mit kritischen Abschnitten
Jeder Prozess verfügt über einen reservierten Codeabschnitt, der als „kritischer Abschnitt“ bezeichnet wird. In diesem Abschnitt kann der Prozess öffentliche Variablen ändern, Tabellen aktualisieren, in Dateien schreiben usw. Bei kritischen Abschnitten ist vor allem zu beachten, dass während ein Prozess in seinem kritischen Abschnitt ausgeführt wird, andere Prozesse in ihrem kritischen Abschnitt nicht ausgeführt werden können. Jeder Prozess muss eine Erlaubnis anfordern, bevor er seinen kritischen Abschnitt betritt. Der Codeabschnitt, der diese Anforderung implementiert, ist der
Eintrittsabschnitt, das Ende des Codes ist der
Austrittsabschnitt und der verbleibende Code ist der
verbleibende Abschnitt. Unten ist die Struktur des kritischen Abschnitts eines bestimmten Prozesses P1 angegeben
hat die folgenden drei Anforderungen: Der kritische Abschnitt muss erfüllt sein
Gegenseitig ausschließend- – Wenn ein Prozess davon ausgeht Es wird davon ausgegangen, dass P2 in seinem kritischen Abschnitt nicht ausgeführt werden kann, im Gegensatz zu jedem anderen Prozess, der in dem kritischen Abschnitt ausgeführt wird.
Fortschritt- – Wenn in seinem kritischen Abschnitt kein Prozess ausgeführt wird und es Prozesse gibt, die in den kritischen Abschnitt ihres kritischen Abschnitts eintreten möchten, können nur die Prozesse, die im verbleibenden Teil nicht ausgeführt werden, den Eintritt in den kritischen Abschnitt anfordern Abschnitt, und die Wahl kann auf unbestimmte Zeit verschoben werden.
Begrenztes Warten- – Beim begrenzten Warten gibt es eine Begrenzung dafür, wie oft ein Prozess seinen kritischen Abschnitt betreten kann, nachdem er eine Anforderung zum Betreten seines kritischen Abschnitts ausgegeben hat und bevor der Anforderung stattgegeben wird.
Es gibt zwei Methoden, die üblicherweise in Betriebssystemen verwendet werden, um mit kritischen Teilen umzugehen.
Präemptiver Kernel
– Ein präemptiver Kernel ermöglicht es, einen Prozess zu präemptivieren, während der Prozess präemptiv ausgeführt wird. Läuft im Kernel-Modus.
Nicht-präemptiver Kernel
– Ein nicht-präemptiver Kernel lässt nicht zu, dass Prozesse, die im Kernel-Modus ausgeführt werden, präemptiv ausgeführt werden. Petersons Lösung
Petersons Lösung ist eine klassisch basierte Softwarelösung für das Problem des kritischen Abschnitts. Es beschränkt sich auf zwei Prozesse, die zwischen ihren kritischen und verbleibenden Teilen wechseln. Petersons Teil erfordert die gemeinsame Nutzung von zwei Datenelementen zwischen den beiden Prozessen, nämlich
Intturn;
- Boolean flag[2];
- Hier gibt die Variable turn an, wer an der Reihe ist, den kritischen Abschnitt zu betreten, und das Flag-Array gibt an ob der Prozess darauf vorbereitet ist, in die kritische Zone einzutreten.
Wenn turn == i bedeutet, dass der Prozess Pi seinen kritischen Abschnitt betreten darf.
Wenn Flag[j] TRUE ist, bedeutet dies, dass Prozess j bereit ist, in seinen kritischen Abschnitt einzutreten.
Das Folgende ist die Struktur von Prozess P in der Peterson-Lösung.
Die Peterson-Lösung behält alle drei bei Bedingungen -
Sich gegenseitig ausschließend- − Es kann jeweils nur ein Prozess auf den kritischen Abschnitt zugreifen.
Progress- – Prozesse außerhalb des kritischen Abschnitts verhindern nicht, dass andere Prozesse in den kritischen Abschnitt gelangen.
Begrenztes Warten – Jeder Prozess hat die Möglichkeit, in seinen kritischen Abschnitt einzutreten, ohne auf unbestimmte Zeit warten zu müssen. Synchronisationshardware
wurde mithilfe von zwei Arten von Anweisungen implementiert –
Test und Set()
- swap()
- Test und Set() sind Hardwarelösungen für das Synchronisationsproblem. Darunter befindet sich eine von mehreren Prozessen gemeinsam genutzte Variable namens Lock, die einen Wert von 0 und 1 haben kann, wobei 1 das Erlangen der Sperre und 0 das Aufheben der Sperre bedeutet.
Immer wenn ein Prozess versucht, den kritischen Abschnitt zu betreten, muss er den Sperrwert abfragen. Wenn der Wert von lock 1 ist, müssen sie warten, bis sich der Wert von lock nicht auf 0 ändert.
Im Folgenden ist die sich gegenseitig ausschließende Implementierung von TestAndSet() dargestellt. Das Semaphor S ist eine ganzzahlige Variable, auf die über die beiden atomaren Standardoperationen wait() und signal() zugegriffen werden kann Während ein Prozess den Wert eines Semaphors ändert, können andere Prozesse nicht gleichzeitig mit demselben Semaphorwert arbeiten.
Im Folgenden ist die Implementierung des gegenseitigen Ausschlusses mithilfe von Semaphoren aufgeführt.
Betriebssysteme verwenden zwei Arten von Semaphoren:
Semaphore zählen
- Dieser Semaphortyp. Der Wert kann innerhalb einer unbegrenzten Domäne variieren
Binäres Semaphor
– Der Wert dieses Semaphortyps kann zwischen 0 und 1 variieren. Sie werden auch Mutex-Sperren genannt. Es wird vom Betriebssystem verwendet, um kritische Abschnittsprobleme in mehreren Prozessen zu lösen.
Das obige ist der detaillierte Inhalt vonProzesssynchronisation in C/C++. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!