-
ALLGEMEINER
STAND DER TECHNIK
-
Die
vorliegende Erfindung betrifft Modifikationen von Interprozessbeziehungen
in einem Multiprozessorsystem und Interprozesssignalisierung. Ein Verständnis bestimmter
Interprozessoperationen, wie nachfolgend beschrieben, ist nötig, um
die Erfindung zu verstehen. UNIXTM wird
als ein Beispiel herangezogen.
-
Die
vergangenen Jahre haben einen deutlichen Anstieg der kommerziellen
Popularität
des UNIXTM-Betriebssystems gesehen. Obwohl
UNIXTM ursprünglich nur von Computer-Wissenschaftlern,
Informatik-Studenten und anderen technisch äußerst bewanderten Computer-Nutzern
bevorzugt wurde, wächst
die Vorliebe für
UNIXTM als eine kommerzielle Programmierumgebung,
da diese Studenten in die Erwerbsbevölkerung eintreten und ihre
entwickelten Vorlieben mit sich nehmen. Dementsprechend ist es für einen
Computer-Hersteller
erforderlich, eine UNIXTM- oder UNIXTM-artige Programmierumgebung zusammen mit
ihrer eigenen Hardware bereitzustellen.
-
UNIXTM war jedoch historisch ein Betriebssystem
für Einzelprozessoren:
ursprünglich
für den PDP-11
von Digital Equipment Corporation, später für Mainframes und noch später für Mikroprozessoren
während
des Booms bei Mikrocomputern. Sogar heute existiert nur eine Handvoll
Multiprozessorimplementierungen von UNIXTM.
Der Zessionar dieser Erfindung, Tandem Computers Incorporated, bereitet ein
Verkaufsangebot einer derartigen Multiprozessorimplementierung unter
dem Produktnamen Nonstop Kernel Software („NSK"), Release D30.00, vor. Der UNIXTM-artige Abschnitt von NSK wird als die
Open System Services, kurz „OSS", bezeichnet.
-
Bei
UNIXTM ist ein „Prozess" die dynamische, Laufzeit-Ausführungsform
eines Programms. Das Programm befindet sich typischerweise in einem
statischen Zustand auf einem Speichermedium, wie beispielsweise
einer Platte oder einem Band, während der
Prozess in den Speicher geladen und ausgeführt wird. UNIXTM ist
ein Multitasking-Betriebssystem: Viele Prozesse können im
Wesentlichen gleichzeitig ausgeführt
werden.
-
Bei
UNIXTM kann ein Prozess einen anderen Prozess
durchführen,
indem der Systemaufruf fork( ) durchgeführt wird. Das Ergebnis eines
fork( )-Systemaufrufs ist die Erzeugung eines neuen Prozesses, welcher
eine Kopie des alten Prozesses ist, außer dass er unter anderem seine
eigene eindeutige Prozess-Identifikationsnummer aufweist. Dieser
Vorgang eines Prozesses, welcher eine Kopie von sich selbst erzeugt,
wird „Aufspaltung" genannt.
-
Ein
Prozess kann auch „exec", was bedeutet, dass
ein Prozess den Programm-Code verändern kann, welchen er ausführt, indem
ein neues Programm eingelesen wird – typischerweise wieder von Platte
oder Band –,
sein altes Programm mit diesem neuen Programm überschrieben wird und das neue Programm
vom Anfang durchgeführt
wird. Ein Prozess kann dies erreichen, indem er den exec( )-Systemaufruf
aufruft.
-
Bei
einer Aufspaltung wird der ältere
Prozess die „Mutter" genannt, und der
neuere Prozess wird die „Tochter" genannt. Natürlich kann
eine Mutter viele Töchter
aufweisen, während
eine Tochter nur eine Mutter aufweist. UNIXTM gestattet
Prozessen jedoch, andere Interprozessbeziehungen zu unterhalten,
wie beispielsweise die Prozessgruppenbeziehung. Jeder Prozess ist
ein Mitglied einer Prozessgruppe. Die vorgegebene Prozessgruppe
eines Prozesses ist die Prozessgrup pe seiner Mutter. Ein Prozess
kann seine Prozessgruppe verändern,
indem er den entsprechenden Systemaufruf ausführt, typischerweise setpgid(
). Dementsprechend kann ein Tochterprozess wählen, in der gleichen Prozessgruppe
wie seine Mutter oder in irgendeiner anderen Prozessgruppe zu sein.
Eine Prozessgruppe kann einen oder mehrere Prozesse als Mitglieder
aufweisen.
-
Die
Prozessgruppenzugehörigkeit
ist wichtig, da das Auftreten eines Ereignisses innerhalb des Systems
erfordern kann, dass es an mehrere Prozesse übermittelt wird. Die Prozessgruppe
kann alle Prozesse identifizieren, welche über das Ereignis benachrichtigt
werden müssen.
Um ein Standardbeispiel anzuführen,
wird angenommen, dass ein Benutzer sich auf einem UNIX-System anmeldet.
Der „Einloggen"-Prozess, durch welchen
der Benutzer zuerst mit dem System kommuniziert, weist eine Prozessgruppe
auf. Der Einloggen-Prozess führt
typischerweise einen Befehlsinterpretierer (eine „Shell") aus, um dem Benutzer
zu ermöglichen,
Befehle und Programme der Shell auszuführen. Das Ausführen eines Programms
der Shell bringt eine Aufspaltung und dann das Ausführen des
Programms mit sich, wie oben stehend beschrieben. Folglich wird
das neu ausgeführte
Programm die gleiche Prozessgruppe wie die Shell, seine Mutter,
aufweisen. Tatsächlich weist
jedes Programm, welches von der Shell ausgeführt wird, seine Töchter, seine
Enkel usw. die gleiche vorgegebene Prozessgruppe auf. Falls jetzt
die Kommunikationsleitung zwischen dem Benutzer und der Shell mit
Absicht oder auf andere Weise unterbrochen wird, ist dann die bevorzugte
Aktion für
die Shell und jeden Prozess, welcher ein Nachfahre der Shell ist, über dieses
Ereignis benachrichtigt zu werden und sich selbst abzubrechen. (Der
Abbruch eines Prozesses wird als „Verlassen" bezeichnet. Ein Verlassen tritt als
ein Ergebnis des Aufrufens des Systemaufrufs exit( ) auf.)
-
Der
Mechanismus bei UNIXTM für ein Benachrichtigen von Prozessen über asynchrone
Ereignisse wird Signalisierung genannt. Prozesse können sich
unter Verwendung des Systemaufrufs kill( ) gegenseitig Signale senden.
Das Betriebssystem selbst kann Signale an Prozesse senden. Ein Prozess
oder das Betriebssystem können
einer Prozessgruppe ein Signal senden. Ein Senden eines Signals
wird als Signalisierung bezeichnet.
-
Aus
dem oben Stehenden ist offenkundig, dass das herkömmliche
Multi-Threading-Paradigma von UNIXTM eine
im Wesentlichen asynchrone Modifizierung von Interprozessbeziehungen,
z. B. durch Aufspaltung und durch Verlassen, gestattet. Mit derartigen
asynchronen Interprozessbeziehungsmodifikationen taucht jedoch die
Frage auf, wie garantiert ein UNIXTM-Betriebssystem atomare
und geordnete Modifikationen von Interprozessbeziehungen?
-
Aus
dem oben Stehenden ist auch offenkundig, dass das herkömmliche
Multi-Threading-Paradigma von UNIXTM eine
asynchrone Modifizierung von Interprozessbeziehungen gestattet,
während eine
Signalisierung auftritt. Wie garantiert beispielsweise ein System
eine atomare, geordnete Signallieferung in Gegenwart einer Aufspaltung?
Ein spezifisches Beispiel des Signalisierungsproblems wird in POSIX,
wie nachfolgend diskutiert, im Abschnitt B.3.1.1 präsentiert.
-
Bei
den historischen Einprozessor-UNIXTM-Implementierungen
stellt die Asynchronizität
einer Interprozessbeziehungsmodifizierung und einer Signalisierung
kein wesentliches Problem hinsichtlich der Atomarität und der
Ordnung dar. Eine Implementierung eines Aufrufs zum Modifizieren
einer Interprozessbeziehung könnte
einen nicht unterbrechbaren (zumindest im kritischen Zustand) Zugriff auf
den zugrunde liegenden Kern einbeziehen. Folglich könnte die
Interprozessbeziehungsmodifizierung an Stelle des einen Prozesses
durchgeführt
werden, während
ein anderer Prozess, welcher Interprozessbeziehungen modifizieren
möchte,
gesperrt werden würde.
-
Ähnlich würde ein
kill( )-Aufruf zu einer einzelnen Übertragung durch den Kern führen, wobei der
Kern an Stelle eines Prozesses ein Signal erzeugt und dieses Signal
im Wesentlichen gleichzeitig an alle Prozesse in der signalisierten
Prozessgruppe liefert. Während
der Kern die Mechanik der Signalisierung durchführt, kann er alle Prozesse
von einer Ausführung
ausschließen,
welche gleichzeitig Prozessgruppenzugehörigkeiten modifizieren würden.
-
Die
Probleme einer atomaren und geordneten Modifizierung von Interprozessbeziehungen
und eine atomare, geordnete Signallieferung sind bei Multiprozessorimplementierungen
von UNIXTM viel schwerer zu behandeln. Multiprozessorumgebungen stellen
auch die Frage nach der Betriebssicherheit: Wie stellt das Multiprozessorsystem
konsistente Interprozessbeziehungen in Gegenwart eines versagenden
Prozessors oder versagender Prozessoren sicher? Wie garantiert der
Multiprozessor eine sichere Signallieferung, wenn Prozessoren versagen? Eine
der Tatsachen von Multiprozessorsystemen – zumindest Multiprozessoren
ohne gemeinsam genutzten Speicher –, welche die schwere Behandelbarkeit
der Atomarität,
der Ordnung und der Betriebssicherheitsprobleme erhöht, ist,
dass die Prozesse in einer Prozessgruppe über mehr als einen Prozessor verteilt
sein können
und gewöhnlich
verteilt sind. Die Einprozessorlösung,
bei welcher der Kern alle potenziellen Konflikte des Zeitverhaltens
durch Single-Threading löst,
ist in der Multiprozessorumgebung nicht verfügbar: Es gibt mehrere Kerne,
welche asynchron arbeiten, und auf jedem Kern gibt es mehrere Prozesse,
welche alle asynchron laufen. Bei unabhängigem Agieren kann jeder Prozessor
nur die sichere und geordnete Modifizierung von Interprozessbeziehungen
auf diesem Prozessor sicherstellen. Beispielsweise kann auf einem
ersten Prozessor ein erster Prozess ein Signal für eine Lieferung an eine Prozessgruppe erzeugen.
Die Prozessgruppe weist Prozesse einschließlich des ersten Prozesses
und eines zweiten Prozesses auf einem zweiten Prozessor auf. Zum
gleichen Zeitpunkt, zu welchem der erste Prozess ein Signal für die Prozessgruppe
erzeugt, spaltet der zweite Prozess einen dritten Prozess auf, welcher
für eine
begrenzte Zeit auch ein Mitglied dieser Prozessgruppe ist und dann
seine Prozessgruppenzugehörigkeit ändert. Empfängt der
dritte Prozess das Signal, welches vom ersten Prozess erzeugt wurde,
oder nicht? Folglich beginnt sich das viel gewünschte Paradigma des Multiprozessorsystems
als einfach eine leistungsfähigere
oder schnellere Version des Einprozessorsystems aufzulösen. Ohne
eine Auflösung
dieser Atomaritäts-,
Ordnungs- und Betriebssicherheitsprobleme kann das Multiprozessorsystem
nicht die gleichen Dienste wie ein Einprozessor-UNIXTM-System,
welches eine Signalisierung implementiert, anbieten. Insbesondere
kann ein Multiprozessorsystem nicht vollständig die Systemdienste anbieten,
welche in POSIX ausführlich
beschrieben sind.
-
Tatsächlich ist
das Problem in Multiprozessorsystemen so schwer zu behandeln, dass
es bewirkt, dass Anbieter derartiger Hardware Software-Produkte
ohne eine Lösung
anbieten. Die Implementierungen LOCUS TNC, MACH, OSF1 und ISIS werden
wiederum nachfolgend beschrieben. Locus weist ein Produkt auf, welches
LOCUS TNC genannt wird. LOCUS TNC implementiert ein verteiltes UNIXTM-System auf der Grundlage einer „vproc"-Abstraktion. Ein
vproc ist eine Datenstruktur, welche sich nur auf einen Prozess
bezieht. Kopien eines einzelnen vproc können in den Speichern existieren, welche
vielen Prozessoren zugeordnet sind. Ein „Eigentümer-" oder „Master-"Prozessor beschreibt den eigentlichen
Prozess mit einer nicht bezüglichen
Datenstruktur. Auf einer Übersichtsebene
gestattet die vproc-Abstraktion den Prozessoren, welche vprocs aufweisen,
sich nicht im Gleichschritt mit der Master-Kopie zu befinden, und
die lokale Kopie wird für manche
Operationen verwendet. Folglich spart das System die Kosten mancher
Nachrichten zwischen dem Master-Prozessor
und einem modifizierenden vproc-Prozessor ein. Es wird angenommen,
dass LOCUS TNC die oben stehend beschrieben Atomaritäts-, Ordnungs-
und Betriebssicherheitsbedingungen nicht korrekt behandelt.
-
MACH,
welches von International Business Machines in Armonk, New York,
erhältlich
ist, und OSF1, welches von der Open Software Foundation, Cambridge,
Massachusetts, erhältlich
ist, sind auch Multiprozessor-UNIXTM-Implementierungen.
Die MACH-/OSF1-Lösung
bezieht einen „UNIXTM-Server",
einen einzelnen, Multi-Threaded-Prozess ein, welcher Prozessbeziehungen
unterhält.
Dieser Prozess ist nicht verteilt. Es gibt nur eine einzelne Kopie. Folglich
spricht er den hier diskutierten, verteilten Algorithmus nicht an.
-
ISIS
löst einen ähnlichen
Satz von Problemen für
ein Ordnen von Nachrichten und für
eine Prozessgruppenzugehörigkeit – jedoch
unter Verwendung einer unterschiedlichen Definition einer „Prozessgruppe" und nicht für eine Signalisierung.
ISIS versucht nicht, UNIXTM-artige Semantik
zu implementieren.
-
Ein
Beispiel eines weiteren Systems, welches keine UNIX
TM-artige Semantik implementiert,
jedoch das Problem der Atomarität
in einem Multiprozessorsystem mit mehreren Prozessoren anspricht, welche
alle globale Daten aufweisen, welche in einem nicht gemeinsam genutzten
Speicher repliziert werden, wird in
EP
369 265 beschrieben. Bei diesem System kommunizieren die
Prozessoren über
den System-Bus miteinander und müssen
um einen Zugriff auf den Bus konkurrieren, wann immer einer der Prozessoren
globale Daten modifizieren möchte. Wenn
ein Prozessor einmal Zugriff auf den Bus besitzt, platziert er die
Speicheradresse und die zu schreibenden Daten in Übereinstimmung
mit dem Busprotokoll auf dem Bus, der Schreibbefehl wird dann an
den entsprechenden Speicher gerichtet und darin für eine sofortige
oder verzögerte
Ausführung zwischengespeichert.
Falls der Prozessor eine Lese- oder Schreiboperation ausführen möchte, setzt
er ein SPERR-Signal logisch wahr, welches den System-Bus sperrt
und die Kontrolle über
ihn behält,
bis die SPERRE vom Prozessor logisch unwahr gesetzt wird.
-
Es
gibt keine bekannten Implementierungen einer atomaren, geordneten
und sicheren Modifizierung von Interprozessbeziehungen oder einer
Signallieferung in einem verteilten Prozessorsystem und insbesondere
in einem Multiprozessorsystem ohne gemeinsam genutztem Speicher.
Tatsächlich
hat Tandem Computers Incorporated vor der anhängigen Freigabe von NSK mit
OSS keine derartigen Merkmale in seiner UNIXTM-artigen Betriebssystemssoftware
angeboten.
-
Zusammen
mit Vorfahren und Prozessgruppenzugehörigkeiten, ist eine andere
UNIXTM-Interprozessbeziehung die „Sitzung". Eine Sitzung ist
eine Ansammlung von Prozessgruppen, welche Benutzern gestatten,
selektiv die Ausführung
von Prozessen auszusetzen und ihre Ausführung zu einem späteren Zeitpunkt
wieder aufzunehmen. Jede Prozessgruppe ist ein Mitglied einer Sitzung,
und ein Prozess ist ein Mitglied der Sitzung, in welcher seine Prozessgruppe
ein Mitglied ist.
-
Es
gibt bei UNIXTM andere Interprozessbeziehungen,
wobei die genannten drei einfach die primären sind. Die Primären reichen
jedoch aus, um zu illustrieren, dass bestimmte UNIXTM-Funktionen
auf individuellen Prozessen oder Prozessgruppen, Sitzungen oder
anderen Interprozessbeziehungen arbeiten. Bei einer Multiprozessorumgebung
können die
simultanen, asynchronen Operationen, welche diese Interprozessbeziehungen
manipulieren, zahlreiche Wettlaufsituationen erzeugen, da die Prozesse
auf verschiedenen Prozessoren verteilte Datenstrukturen modifizieren.
-
KURZFASSUNG DER ERFINDUNG
-
Dementsprechend
ist eine Aufgabe der Erfindung, in einem UNIXTM-artigen
Multiprozessorsystem das Ordnen von Operationen, welche eventuell eine
Interprozessbeziehung modifizieren können, wobei Wettläufe und
andere, nicht deterministische Verhaltensweisen abhängig vom
Zeitverhalten der Zugriffe auf eine verteilte Datenstruktur unmöglich gemacht
werden.
-
Eine
andere Aufgabe der Erfindung ist ein UNIXTM-artiges
Multiprozessorsystem, wobei das Versagen eines Prozessors, welcher
gerade eine Interprozessbeziehung modifiziert, entweder zu keiner Veränderung
oder zu einer Veränderung
führt,
welche unter allen überlebenden
Prozessen über
alle überlebenden
Prozessoren hinweg konsistent ist.
-
Noch
eine andere Aufgabe der Erfindung ist eine UNIXTM-artige Implementierung
auf einem verteilten Verarbeitungssystem, welches geordnete und sichere
Interprozessbeziehungsmodifikationen zusammen mit gutem Leistungsvermögen zeitkritischer Funktionen
aufweist.
-
Diese
und andere Aufgaben der Erfindung werden beim Lesen der nachfolgenden
Offenbarung unmittelbar offenkundig.
-
Dementsprechend
wird hier nachfolgend eine Multiprozessorimplementierung eines UNIXTM-artigen Betriebssystems beschrieben, wobei Interprozessbeziehungen
in Kopien von Datenstrukturen repräsentiert werden, welche in
den nicht gemeinsam genutzten Speichern der Prozessoren des Multiprozessorsystems
repliziert werden. Jeder Prozessor, welcher eine Interprozessbeziehung
modifizieren möchte,
muss in eine Konkurrenz um eine Interprozessorsperre eintreten,
welche durch einen Steuerungsprozessor unterhalten wird. Die Interprozesssperre
kann für
die bestimmte Interprozessbeziehung, welche modifiziert werden soll,
für irgendeine
Un tergruppe aller Interprozessbeziehungen oder allgemein für alle Interprozessbeziehungen
spezifisch sein.
-
Wenn
der anfordernde Prozessor beim Erwerben der Interprozessorsperre
erfolgreich ist, informiert der Prozessor dann jeden Prozessor – in einer vorbestimmten
Reihenfolge – über die
Modifizierung der Interprozessbeziehung. Der anfordernde Prozessor
gibt die Interprozessbeziehungssperre dann frei.
-
Wenn
der anfordernde Prozessor die Interprozessorsperre nicht erwirbt,
wartet der anfordernde Prozessor, bevor er erneut in eine Konkurrenz
eintritt. Typischerweise wird der anfordernde Prozessor solche Prozesse
ablaufen lassen, welche keine Interprozessorsperre erfordern, während er
darauf wartet, wieder in die Konkurrenz einzutreten.
-
Jeder
Prozessor, welcher eine Benachrichtigung über eine Modifizierung einer
Interprozessbeziehung empfängt,
verändert
seine lokale Kopie der Datenstruktur, welche diese Interprozessbeziehung repräsentiert,
um der Modifizierung zu entsprechen.
-
Jeder
empfangende Prozessor, wenn er einmal die eingehende Modifizierungsbenachrichtigung empfangen
hat, arbeitet gegenüber
allen anderen Prozessoren asynchron. Alle Aktionen des empfangenden
Prozessors vor oder nach der Aktualisierung dürfen nicht und sind nicht mit
den Aktionen jedes anderen Prozessors koordiniert.
-
Beim
Versagen eines modifizierenden Prozessors, welcher die Interprozessorsperre
nicht erworden hat, ist keine Wiederherstellung nötig, um eine
Konsistenz der bestimmten verteilten Datenstrukturen sicherzustellen.
Beim Versagen eines modifizierenden Prozessors, welcher die Interprozessorsperre
erworben hat, übernimmt
der Steuerungsprozessor die Funktion des Informierens aller empfangender
Prozessoren über
die Modifizierung.
-
Beim
Versagen des Steuerungsprozessors folgen die überlebenden Prozessoren einer
vorbestimmten Prozedur, um zu bestimmen, welchem der überlebenden
Prozessoren es gelingt, der Steuerungsprozessor zu sein.
-
KURZBESCHREIBUNG
DER ZEICHNUNGEN
-
1 ist
eine Schemaansicht des Multiprozessorsystems der Erfindung.
-
2 ist
ein vereinfachtes Diagramm des Zustands der Prozesse im Multiprozessorsystem
der Erfindung.
-
3 ist
ein vereinfachtes Diagramm des Zustands der Prozesse im Multiprozessorsystem
der Erfindung.
-
4 ist
ein vereinfachtes Diagramm des Zustands der Prozesse im Multiprozessorsystem
der Erfindung.
-
BESCHREIBUNG
DER BEVORZUGTEN AUSFÜHRUNGSFORM
-
1 zeigt
das Multiprozessorsystem 1 mit Prozessoren 2a, 2b,
..., 2n. N ist typischerweise sechzehn, obwohl N größer oder
kleiner als sechzehn sein kann. Jeder Prozessor 2 ist an
einen jeweiligen Speicher 3 angeschlossen.
-
Jeder
Prozessor 2 führt
eine Betriebssystemssoftware aus. Bei der bevorzugten Ausführungsform
führen
die Prozessoren 2 alle die gleiche Betriebssystemssoftware
aus. Das zugrunde liegende Betriebssystem G ist der Guardian, welcher
von Tandem Computers Incorporated erhältlich ist, und das überlagerte
Betriebssystem ist NSK mit OSS, eine Implementierung des Portable
Operating System Interface, Teil I („POSIX", International Standard ISO/IEC 9945-1:
1990; IEEE Std 1003.1-1990). OSS wird hier als eine Variante von
UNIXTM betrachtet Als ein Ergebnis des Ausführens von
UNIXTM weist jeder Prozessor 2 Prozesse
P auf. Wie es das Paradigma in UNIXTM-Systemen ist, spalten
Prozesse Töchter auf,
welche wiederum aufspalten, wobei sie ihre eigenen Töchter erzeugen,
und so weiter. Bei der bevorzugten Ausführungsform des Multiprozessorsystems 1 kann
ein Prozess auf Prozessor 2a eine Tochter erzeugen, welche
auf 2a oder auf irgendeinem der Prozessoren 2b, 2c,
..., 2n abläuft. 2 illustriert
die Prozesse im Multiprozessorsystem 1 zum Zeitpunkt t0. Die Prozessoren 2a, 2b und 2c werden
durch ihre jeweiligen Prozesstabellen PT4a, PT4b und PT4c wiedergegeben.
Die Prozesstabellen PT4 sind ein Beispiel einer Interprozessbeziehung
einer verteilten Datenstruktur. Die kumulativen Tabellen, welche UNIXTM-Prozessbeziehungen definieren, sind eine Prozesstabelle.
Die Prozesstabelle ist das Systembetriebsmittel, bei welchem sich
jeder noch vorhandene Prozess auf einem Prozessor befindet.
-
Prozess
P100 befindet sich (R) auf Prozessor 2a. Prozess P100 ist
die Mutter des Prozesses P110, welcher sich nicht auf Prozessor 2a,
sondern auf Prozessor 2b befindet (–R).
Prozess P110 ist wiederum die Mutter des Prozesses P111 auf Prozessor 2c.
Die Prozessgruppe des Prozesses P100 ist Prozessgruppe G1. Wie oben
stehend erklärt,
ist die Prozessgruppe des Prozesses P110 die vorgegebene Prozessgruppe
seiner Mutter, des Prozesses P100. Ähnlich ist die Prozessgruppe
des Prozesses P111 die Prozessgruppe seiner Mutter, P110. Jeder
der Prozesse P100, P110 und P111 ist in Prozessgruppe G1.
-
Man
betrachte die verschiedenen, nachfolgend erklärten Szenarien. Das erste Szenario
wird in 3 illustriert. 3 zeigt
eine Untergruppe der Prozesse, welche im Multiprozessorsystem 1 zu
einem Zeitpunkt t1 vorhanden sind. Zum Zeitpunkt t1, t1 > t0, hat Prozess P100
eine zweite Tochter, Prozess P120, hervorgebracht. Prozess P120
wird mit der Prozessgruppe seiner Mutter, Prozess P100, geboren.
-
Das
zweite Szenario wird in 4 illustriert. 4 zeigt,
dass zum Zeitpunkt t2, t2 > t1 > t0, Prozess P111 gewählt hat,
seine Prozessgruppenzugehörigkeit
von G1 auf G2 zu ändern.
Dementsprechend umfasst Prozessgruppe G1 zum Zeitpunkt t2 die Prozesse
P100, P110 und P120. Prozessgruppe G2 umfasst nur Prozess P111.
-
Wie
es in UNIXTM-Systemen typisch ist, kann Prozess
P110 ein Signal an jeden Prozess P in seiner Prozessgruppe G senden
wollen. Wenn Prozess P110 das Signal zum Zeitpunkt t2 sendet, während P111
seine Prozessgruppenzugehörigkeit ändert, gibt
es dann eine Unbestimmtheit, ob Prozess P111 das Signal empfangen
wird. Abhängig
davon, ob kill( ) oder setpgid( ) den Wettlauf gewinnt, wird das
Signal an die Prozesse P100, P110, P111 und P120 oder nur an die
Prozesse P100, P110 und P120 geliefert. Prozess P111 kann das Signal
empfangen oder nicht.
-
Die
Quelle dieses Nicht-Determinismus ist, dass der empfangende Prozessor 2c unabhängig vom
signalisierenden Prozessor 2b arbeitet. Sogar obwohl die
Prozessoren 2b und 2c nicht die gleiche Operation
durchführen,
Prozessor 2b führt
ein signal( ) durch, während
Prozessor 2c ein setpgid( ) durchführt, ist die zugrunde liegende
Datenstruktur, welche bei beiden Operationen betroffen ist, die
Prozesstabelle PT. Eine Kopie davon wird im Speicher 3 jedes Prozessors 2 unterhalten.
-
Wettlaufbedingungen
treten auch auf, wenn die konkurrierenden Funktionalitäten beide
Interprozessbeziehungsmodifikationen sind. Beispielsweise ist setpgid(
) definiert, nur auf einem Zieltochterprozess zu arbeiten, falls
diese Tochter keinen exec( )-Aufruf durchführt. Es wird angenommen, dass
ein setpgid( )-Aufruf zum gleichen Zeitpunkt erteilt wird, an welchem
eine Tochter einen exec( )-Aufruf erteilt. Entweder sollte der exec(
) zuerst auftreten (und der setpgid( ) versagen), oder der setpgid(
) sollte zuerst auftreten, und der exec( ) tritt später mit
der installierten neuen Gruppen-ID auf.
-
In
US-Patent Nr. 4,718,002 (1988) beschreibt Carr ein Verfahren zur Übermittlung
aktualisierter Informationen unter Prozessoren in einem Multiprozessorsystem,
wie beispielsweise System 1, eine globale Aktualisierungsprozedur
(„GLUPP"). Carr strebt danach,
den Stand der Technik einfach fehlertoleranter Systeme durch Erzeugen
eines Systems zu verbessern, welches gegenüber mehrfachem Versagen tolerant
ist.
-
GLUPP
wird nachfolgend oberflächlich
beschrieben. GLUPP ordnet die Prozessoren 2 doppelt. Die
erste Ordnung ist die vereinbarte und universell bekannte Reihenfolge,
bei welcher die Prozessoren 2 eine globale Aktualisierungsnachricht
empfangen. Die zweite Ordnung ist die vereinbarte und universell bekannte
Abfolge von Prozessoren als Steuerungsprozessor, sollte der ursprüngliche
Steuerungsprozessor (der erste Prozessor in der zweiten Ordnung) versagen.
Jede der beiden GLUPP-Ordnungen ist eigentlich eine Schleife.
-
Bestimmte
verteilte, kritische Datenstrukturen werden durch eine globale Aktualisierungssperre geschützt („GLUPP-Sperre"). Jeder Prozessor 2, welcher
irgendeine derartige verteilte, kritische Datenstruktur verändern möchte, muss
zuerst die GLUPP-Sperre erwerben. Der Steuerungsprozessor ist der
einzige Prozessor, welcher die Sperre unterhält; er vermittelt das Gewähren und
das Verweigern der GLUPP-Sperre.
-
Während sich
Carr der Übermittelung
von Aktualisierungen an verteilte Datenstrukturen angesichts einer
Gefahr eines Prozessorversagens widmet, richtet sich die vorliegende
Erfindung auf Wettlaufsituationen, welche asynchronen, konkurrierenden
Prozessoren, welche Interprozessbeziehungen modifizieren, und asynchronen,
konkurrierenden Prozessoren innewohnen, welche derartige Beziehungen
modifizieren, und ungefähr
zur gleichen Zeit signalisieren. Wie sie modifiziert ist, um UNIXTM-artige Interprozessbeziehungsmodifizierung
und Signalisierung zu implementieren, erfordert GLUPP, dass ein
Prozessor die GLUPP-Sperre erwirbt, falls dieser Prozessor irgendeine
Interprozessbeziehung modifizieren möchte, welche ein anderer Prozessor
gleichzeitig modifizieren kann. Die GLUPP-Sperre muss auch für Operationen
erworben werden, welche die Prozessgruppierung beeinflussen kann,
von welcher die Signalisierung abhängt. Dementsprechend muss jeder
Prozessor, welcher ein Signal für
eine Lieferung an andere Prozesse erzeugt hat, und welcher deshalb
auf die verteilte Prozesstabelle PT4 zugreifen muss, zuerst die
GLUPP-Sperre vom Steuerungsprozessor erwerben. Es muss erwähnt werden,
dass der signalisierende Prozessor 2b im oben stehenden Beispiel
die GLUPP-Sperre erwerben muss, um den Prozessen P in Prozessgruppe
G1 zu signalisieren. (Beim Erwerben der GLUPP-Sperre überträgt ein Prozess 2 eine
Kopie der globalen Aktualisierungsnachricht, welche übertragen
werden soll, mit der Hilfe der GLUPP-Sperre an den Steuerungsprozessor. Der
Steuerungsprozessor unterhält
diese Kopie der globalen Aktualisierungsnachricht in seinem Speicher
für globale
Aktualisierungsnachrichten. Diese Kopie im Speicher für globale
Aktualisierungsnachrichten wird verwendet, wie nachfolgend beschrieben.)
-
Genauso
muss jeder Prozess, welcher sich aufspalten möchte, zuerst die GLUPP-Sperre
vom Steuerungsprozess erwerben. Ein Aufspalten erfordert Zugriff
auf die verteilte Prozesstabelle PT4: Prozesstabelle PT4 ist der
Aufenthaltsort der Prozesse im System 1, welches UNIXTM ausführt.
Deshalb muss Prozess P111 die GLUPP-Sperre erwerben, bevor er seine
Prozessgruppenzugehörigkeit
zum Zeitpunkt t2 verändert.
-
Als
eine Folge der oben stehenden, modifizierten GLUPP wird die Zugehörigkeit
der Prozessgruppe G1 zum Zeitpunkt der Signalisierung festgestellt.
Weil entweder der signalisierende Prozessor 2b oder der
die Gruppe verändernde
Prozessor 2c die GLUPP-Sperre zuerst erwerben muss – und folglich
der andere der Beiden warten muss – wird die Lieferung von Signalen
nebenbei geordnet.
-
Dementsprechend
beschreibt die oben stehende Offenbarung eine Implementierung einer UNIXTM-artigen Signalisierung, wobei ein Signal
bei einer Prozessgruppe sogar dann bei irgendeinem konsistenten
Zustand der Prozessgruppe ankommt, wenn andere Prozessoren versuchen,
die Gruppenzugehörigkeit
zu verändern,
während
die Lieferung des Signals auftritt. Der konsistente Zustand der
Prozessgruppe ist die Prozessgruppe zu dem Zeitpunkt, an welchem
der signalisierende Prozessor die GLUPP-Sperre erwirbt. Andere Prozessoren
können dann
versuchen, sich aufzuspalten, Prozessgruppen zu verändern oder
auf andere Weise Prozessgruppenzugehörigkeiten zu modifizieren,
warten jedoch auf die GLUPP-Sperre, bevor sie dies tun. Die GLUPP-Sperre
wird nur dann wieder verfügbar, wenn
der signalisierende Prozessor seine nötigen Zugriffe auf die verteilte
Prozesstabelle beendet hat. Es ist gewährleistet, dass Veränderungen
der Gruppenzugehörigkeit
und eine Signallieferung in einer bestimmten Reihenfolge auftreten,
und diese Reihenfolge ist bei allen Prozessoren die gleiche.
-
Bei
der modifizierten globalen Aktualisierungsprozedur dieser Erfindung
muss ein signalisierender Prozessor einer signalisierenden Gruppe
G jeden anderen verfügbaren
Prozessor über
das(die) Signal(e) benachrichtigen, welche an die Prozesse geliefert
werden sollen, falls vorhanden, welche Mitglieder der Prozessgruppe
G auf diesem anderen verfügba ren
Prozessor sind. Wenn der signalisierende Prozessor die GLUPP-Sperre
einmal erworben hat, sendet der signalisierende Prozessor ein globales
Aktualisierungsnachrichtenpaket, welches die Signalisierung an jeden
verfügbaren
Prozessor in der Reihenfolge wiederspiegelt, welche durch die erste oben
stehende Ordnung spezifiziert wird. Wenn folglich der signalisierende
Prozess P110 zum Zeitpunkt t3 > t2
ein Signal S1 und S2 an Prozessgruppe G1 senden möchte und
ein signalisierender Prozess P111 auch ein Signal S3 an Prozessgruppe
G1 senden möchte,
wird einer der Prozessoren 2b oder 2c die GLUPP-Sperre
erwerben. Unter der Annahme, dass Prozessor 2c die Konkurrenz
um die GLUPP-Sperre gewinnt, wird Prozessor 2c dann jeden
der empfangenden Prozessoren 2a, 2b, 2c,
..., 2n benachrichtigen. Prozessor 2c benachrichtigt
die Prozessoren in der Reihenfolge, welche in der globalen Aktualisierungsnachrichtenordnung
spezifiziert ist. Die globale Aktualisierungsnachricht, welche an jeden
Prozessor gesendet wurde, gibt die Signalisierung der Prozessgruppe
G mit Signal S3 wieder. Wie es die globale Aktualisierungsprozedur
erfordert, muss jeder empfangende Prozessor eine Bestätigung über die
globale Aktualisierungsnachricht senden. Beim Empfang einer Bestätigung von
einem empfangenden Prozessor in der globalen Aktualisierungsnachrichtenordnung
sendet der signalisierende Prozessor 2c die globale Aktualisierungsnachricht
an den nächsten
Prozessor in der globalen Aktualisierungsnachrichtenordnung. Im
degenerativen Fall benachrichtigt der signalisierende Prozessor 2c sich selbst über die
Signale. Im Fall des Nicht-Versagens zeigt
die Bestätigung
des empfangenden Prozessors 2 an, dass dieser Prozessor 2 das
Signal S3 geliefert hat, welches im globalen Aktualisierungsnachrichtenpaket
an jeden Prozess, falls vorhanden, in Prozessgruppe G1 des empfangenden
Prozessors 2 repräsentiert
ist. Falls der empfangende Prozessor der Prozessor 2a ist,
wird dann jeder der Prozesse P100 und P120 S3 zum Zeitpunkt empfangen
haben, an welchem Prozessor 2a die globale Aktualisierungsnachricht
vom signalisierenden Prozessor 2c bestätigt. Falls der emp fangende
Prozessor 2c ist, wird dann kein Prozess auf Prozessor 2c das
Signal S3 zum Zeitpunkt empfangen haben, an welchem Prozessor 2c die
globale Aktualisierungsnachricht vom signalisierenden Prozessor 2c bestätigt.
-
Wenn
der signalisierende Prozessor 2c die globale Aktualisierungsnachricht
einmal verteilt hat, welche das Senden des Signals S3 an Prozessgruppe
G1 repräsentiert,
gibt dann Prozessor 2c die GLUPP-Sperre frei. Der signalisierende
Prozessor 2b konkurriert jetzt um die Sperre, um die Signale
S1 und S2 zu senden. Auf die gleiche modifizierte GLUPP folgend
liefert der signalisierende Prozessor 2b Signale der globalen
Aktualisierungsnachricht, welche das Senden der Signale S1 und S2
an Prozessgruppe G repräsentiert.
-
Wie
das oben Stehende zeigt, empfängt
jeder der Prozesse P100, P110 und P120, aus welchen Prozessgruppe
G1 zusammengesetzt ist, zuerst das Signal S3 und dann die Signale
S1 und S2.
-
Dementsprechend
beschreibt oben stehende Offenbarung eine UNIXTM-artige
Signalisierungsimplementierung, wobei alle Signale von jedem signalisierenden
Prozessor bei allen Mitgliedern der Prozessgruppe G entweder vor
oder nach denjenigen ankommen, welche von allen anderen signalisierenden
Prozessoren gesendet wurden, wenn mehrere signalisierende Prozessoren
Prozessgruppensignale an eine Prozessgruppe G senden. Die Prozessgruppenmitglieder
sehen immer die gleichen eingehenden Signale in der gleichen Reihenfolge.
-
Wenn
im modifizierten GLUPP der Steuerungsprozessor feststellt, dass
ein Prozessor 2 versagt hat, prüft der Steuerungsprozessor,
ob eine globale Aktualisierung im Gange war, d. h. ob die GLUPP-Sperre
von einem signalisierenden Prozessor erworben wurde. Der Steuerungsprozessor
muss keine Wiederherstellung durchführen, falls die GLUPP-Sperre
nicht so erworben wurde.
-
Wenn
die GLUPP-Sperre erworben wurde, übernimmt der Steuerungsprozessor
selbst die Aufgabe des Sendens der globalen Aktualisierungssignalnachricht
an jeden Prozessor. Der Steuerungsprozessor rekonstruiert die globale
Aktualisierungssignalisierungsnachricht, welche der signalisierende Prozessor
gerade geliefert hat als er versagte, aus seinem Speicher für globale
Aktualisierungsnachrichten. Der Steuerungsprozessor wird dann praktisch
der signalisierende Prozessor, welcher die globale Aktualisierungssignalnachricht
wiederum gemäß der globalen
Aktualisierungsnachrichtenordnung an jeden Prozessor sendet. Wenn
folglich Prozessor 2a dem Prozess G1 Signal S1 signalisieren möchte und
wenn Prozessor 2d (nicht gezeigt) der Steuerungsprozessor
ist, dann fordert Prozessor 2a die GLUPP-Sperre des Steuerungsprozessors 2d an.
Beim Empfang der Anforderung und falls kein anderer Prozessor die
GLUPP-Sperre schon erworben hat, kopiert Prozessor 2d die
globale Aktualisierungssignalisierungsnachricht in seinen Speicher
für globale
Aktualisierungsnachrichten und benachrichtigt den signalisierenden
Prozessor 2a, dass er die GLUPP-Sperre erworben hat. Unter
der Annahme, dass die globale Aktualisierungsnachrichtenordnung 2a, 2b, 2c,
... 2n ist, liefert der signalisierende Prozessor 2a dann
die globale Aktualisierungssignalisierungsnachricht S1 an sich selbst
und bestätigt
sich selbst. Der signalisierende Prozessor 2a sendet als Nächstes die
globale Aktualisierungsnachricht an den empfangenden Prozessor 2b,
und Prozessor 2b bestätigt.
Dann wieder sendet der signalisierende Prozessor 2a die
globale Aktualisierungsnachricht an den empfangenden Prozessor 2c und
wartet auf Bestätigung.
Es wird jetzt angenommen, dass Prozessor 2a vor einem Empfang
der Bestätigung
des empfangenden Prozessors 2c versagt. Dann wird der Steuerungsprozessor 2d schließlich das
Versagen des Prozessors 2a erfassen. Steuerungsprozessor 2d erzeugt
dann die globale Aktualisierungssignalisierungsnachricht S1 aus
seinem Speicher für
globale Aktualisierungsnachrichten. Mit dieser regenerier ten Kopie
wird der Steuerungsprozessor 2d praktisch der signalisierende
Prozessor. Er geht durch die globale Aktualisierungsnachrichtenordnung
und sendet die Kopie der globalen Aktualisierungsnachricht der Reihe
nach an jeden Prozessor 2b, 2c, ..., 2n.
(Steuerungsprozessor 2d weiß, dass Prozessor 2a nicht verfügbar ist.)
-
Typischerweise
sind UNIXTM-Prozesse nicht in der Lage zu
unterscheiden, wie viele eines bestimmten Signaltyps empfangen wurden.
Dementsprechend ist es für
einen empfangenden Prozessor 2 nicht erforderlich, eine
doppelte globale Aktualisierungssignalisierungsnachricht zurückzuweisen.
Bei der bevorzugten Ausführungsform
werden jedoch empfangende Prozessoren angepasst, doppelte globale
Aktualisierungsnachrichten zurückzuweisen. Beispielsweise
unterhält
jeder Prozessor 2 einen eindeutigen globalen Aktualisierungsnachrichten-ID-Zähler. Diese
mehreren Zähler
können
beim Systemstart synchronisiert werden. Jede globale Aktualisierungsnachricht,
welche unter der GLUPP-Sperre verteilt wurde, umfasst die eindeutige globale
Aktualisierungsnachrichten-ID vom veranlassenden Prozessor 2,
und jeder empfangende Prozessor 2 inkrementiert seinen
eindeutigen globalen Aktualisierungsnachrichten-ID-Zähler beim
Empfang einer globalen Aktualisierungsnachricht, deren ID mit dem
Zähler
des empfangenden Prozessors 2 übereinstimmt. Wenn Steuerungsprozessor 2d in
seiner Rolle als der signalisierende Prozessor nun eine doppelte
globale Aktualisierungssignalisierungsnachricht an Prozessor 2c liefert,
kann Prozessor 2c bestätigen,
ansonsten jedoch die globale Aktualisierungssignalisierungsnachricht
ignorieren, da die globale Aktualisierungsnachrichten-ID der globalen
Aktualisierungsnachricht und der entsprechenden ID im globalen Aktualisierungsnachrichten-ID-Zähler des Prozessors 2b nicht übereinstimmen.
Prozessor 2c würde ähnlich die
doppelte globale Aktualisierungssignalisierungsnachricht vom Steuerungsprozessor 2d ignorieren.
-
Dementsprechend
beschreibt oben stehende Offenbarung eine UNIXTM-artige
Signalisierungsimplementierung, wobei, falls ein signalisierender Prozessor
während
der Signalisierungsoperation versagt, die Signale dann entweder
an keinen Prozess geliefert werden oder an alle überlebenden Mitglieder der
Prozessgruppe geliefert werden: Falls der signalisierende Prozessor
vor einem Erwerben der GLUPP-Sperre versagt, findet die Signalisierungsaktion
dann niemals statt – noch
nicht einmal auf dem signalisierenden Prozessor. Falls der signalisierende Prozessor
nach einem Erwerben der GLUPP-Sperre und vielleicht nach einem Liefern
einer Signalanforderung an irgendeinen der empfangenden Prozessoren
versagt, versucht dann die GLUPP erneut, die gleiche globale Aktualisierungssignalisierungsnachricht
unter Verwendung eines überlebenden
Prozessors zu senden, bis es keine überlebenden Prozessoren gibt.
Folglich kann der signalisierende Prozessor versagen, jedoch liefert
ein überlebender
Prozessor das gleiche Signal an alle anderen Prozessoren. Die globale
Aktualisierungsnachrichten-ID gestattet, dass jede eingehende Anforderung
als „neu" im Gegensatz zu „gesehen
und darauf reagiert" identifiziert wird.
Die doppelten Anforderungen werden einfach ignoriert. Kurz gesagt
wird ein Signal niemals teilweise oder zweimal an eine Prozessgruppe
geliefert.
-
Bei
der hier beschriebenen, modifizierten GLUPP ist das Versagen eines
empfangenden Prozessors 2 im Allgemeinen ohne Konsequenz.
Da jeder Prozessor nur für
ein Liefern von Signalen an Prozesse P auf diesem empfangenden Prozessor 2 verantwortlich
ist, hinterlässt
das Versagen dieses empfangenden Prozessors 2 mit einer
Ausnahme keine unerledigten oder unberücksichtigten Aufgaben. Falls
der empfangende Prozessor 2, welcher versagt, der Steuerungsprozessor
ist, bleiben dann wesentliche Aufgaben unberücksichtigt. Carr beschreibt
eine Prozedur für
ein Versagen eines Sperrprozessors in einem Multiprozessorsystem,
welches globale Ak tualisierungen durchführt. Diese Prozedur arbeitet
innerhalb dieses modifizierten GLUPP-Kontextes.
-
Die
oben stehenden Prozeduren reichen aus, um jede Anzahl versagender
Prozessoren im System 1 abzudecken. Ein mehrfaches Versagen von
Prozessoren kann in eine Kombination oben stehender Szenarien zerlegt
werden.
-
Dementsprechend
beschreibt oben stehende Offenbarung eine UNIXTM-artige
Signalisierungsimplementierung, wobei, wenn ein empfangender Prozessor
versagt, es ohne Konsequenz ist, wie weit diesem empfangenden Prozessor
ein Liefern der Signale an die Prozessgruppenmitglieder gelungen
ist, welche sich auf diesem Prozessor befinden. Ein empfangender
Prozessor ist nur für
eine Behandlung der Prozessgruppenmitglieder verantwortlich, welche sich
auf diesem empfangenden Prozessor befinden.
-
Andere
Ausführungsformen
liegen mit Absicht innerhalb des Schutzumfangs der begleitenden Ansprüche.