Zum Inhalt springen

Betriebssystemtheorie/ Prozesse

Aus Wikibooks


Definition

[Bearbeiten]

Prozesse bilden eine grundlegende Struktur jedes modernen Betriebssystems. Die häufigste Definitionen eines Prozesses lautet "ein Programm in Ausführung" oder "ein geladenes Programm mit seinen Betriebsmitteln". Eine einheitliche, formale Definition ist leider nicht einfach oder möglich, da die Eigenschaften eines Prozesses sehr stark vom zugrunde liegenden System abhängig sind. Die folgenden Prozessmerkmale sind aber allen modernen Betriebssystemen gemein:

  • Jeder Prozess besitzt seinen eigenen virtuellen Adressraum für Arbeitsspeicher, welcher ihn von anderen Prozessen im System trennt.
  • Jeder Prozess enthält mindestens einen Thread, der prinzipiell gerechnet werden kann. Dieser Thread kann blockiert sein, falls er auf eine Ressource oder ein Ereignis wartet, muss aber gültige Instruktionen enthalten.
  • Jedem Prozess sind die von ihm benutzten Ressourcen zugeordnet. Dazu gehören offenen Dateien, Netzwerkverbindungen, Hardwaregeräte und ähnliches.

Die genauen Details unterscheiden sich von System zu System. Zum Beispiel ist in vielen eingebetteten Systemen keine Unterstützung von virtuellen Speicheradressen vorgesehen. Alle Prozesse teilen sich den physischen Speicher durch direkte Adressierung. In UNIX-Systemen erfolgt der Zugriff auf Hardware über das Dateisystem. Dazu existieren Dateien, die das jeweilige Gerät abstrahieren. Somit sind die Ressourcen für Dateien und Hardwaregeräte aus der Sicht des Prozesses identisch.

Die Erschaffung neuer Prozesse

[Bearbeiten]

Alle Betriebssysteme bieten die Möglichkeit neue Prozesse zu erstellen. Das System stellt dafür einen oder mehrerer Systemaufrufe zur Verfügung, um den bereits existierenden Prozessen zu ermöglichen einen neuen "Mitstreiter" ins Leben zu rufen. Im Wesentlichen gibt es 3 Möglichkeiten:

  • Erstellen eines neuen Prozesses: Diese Methode erstellt einen leeren Prozess ohne irgendwelche zugeordneten Ressourcen. Die Methode wird beispielsweise von den L4-Mikrokernen verwendet. L4 implementiert den Systemaufruf l4_task_new(), mit dem ein neuer Prozess erstellt wird. Das "Auffüllen" des Prozesses mit Daten und Anweisungen wird von einem bereits existierenden Prozess übernommen, welcher dem "Neuankömmling" Speicherseiten in den Adressraum einblendet.
  • Kopieren eines bestehenden Prozesses: Hier wird eine exakte Kopie eines bereits laufenden Prozesses erstellt und als neuer Prozess in das System eingefügt. UNIX bietet hierzu den Systemaufruf fork(). Jeder UNIX-Prozess, der fork() aufruft, erstellt eine Kopie von sich und seinem aktuellen Zustand. Der neue Prozess kann nun unabhängig vom Eltern-Prozess weiterarbeiten und zum Beispiel ein neues Programm laden. Mehr dazu im nächsten Punkt.
  • Ersetzen eines vorhandenen Prozesses: erzeugt streng genommen keinen neuen Prozess sondern setzt einen Prozess im System auf einen neuen Zustand. Beim Programmstart in UNIX ist dies meist der zweite Schritt nach fork(). Ein mit fork() erstellter Kind-Prozess führt den Systemaufruf exec() aus, welcher eine ausführbare Datei lädt und ihre Anweisungen ausführt. Der alte Prozesszustand geht hierbei weitestgehend verloren.

Generell gilt: neue Prozesse werden von bereits existierenden Prozessen erstellt. Wenn man diese Aussage zu Ende denkt, taucht die Frage auf, wo der erste Prozess entsteht. Die Antwort unterscheidet sich wieder von System zu System. Betriebssysteme, die von UNIX abstammen, erstellen nach dem Laden des Systemkerns den sogenannten Init-Prozess und lassen diesen die Datei /sbin/init ausführen. Der weitere Bootvorgang wird nun durch diesen Prozess gesteuert. Andere Systemen bieten die Option über Parameter beim Bootvorgang zu steuern, welche Dateien als neue Prozesse zu Beginn geladen werden. Da es sich hier meist um einfache Mechanismen handelt, sind die Möglichkeiten allerdings sehr begrenzt. Prozesse, die direkt vom Kern gestartet werden, dienen vor allem dem Abschluss des Bootvorgangs oder sind Teil eines sehr dedizierten und spezialisierten Computersystems.

Zustandsformen

[Bearbeiten]

Prozesse kennen verschiedene Zustände, die sie während ihrer Ausführung erreichen können.

created
Der Prozess wurde in die Prozessliste eingetragen, die Daten und der Programmcode geladen, aber er wurde noch nicht in die Ready-Queue zugelassen (z.B. vom Scheduler).
running
Der Prozess wird gerade ausgeführt. Dazu muss mindestens einem Thread des Prozesses eine CPU zugeteilt worden sein.
ready
Der Prozess ist bereit zur Ausführung und wartet auf die Zuteilung von Zeitscheiben. Dies ist der Fall, falls mindestens ein Thread des Prozesses ready ist.
blocked/ waiting
Der Prozess ist blockiert. Dieser Zustand tritt auf, falls alle Threads des Prozesses blockiert sind.
dead
Der Prozess wurde beendet. Wenn alle Threads eines Prozesses beendet wurden, gilt auch der Prozess als beendet.

Der Lebenszyklus von Prozessen ist eng mit dem Zustand seiner Threads verknüpft und beginnt im Zustand ready. Jeder Prozess startet mit einem einzigen bereiten Thread. Diesem Thread wird vom CPU-Scheduler Rechenzeit zugeteilt. Dadurch wird der Thread in eine CPU geladen und der Threadzustand auf running gesetzt. Nach dem Ende aller zugeteilten Rechenzeit wechselt der Thread wieder auf ready.

Laufende Threads können blockieren. Dies geschieht, falls sie auf externe Ereignisse warten oder auf Ressourcen zugreifen wollen, die bereits von anderen Threads belegt sind. Dabei spielt es keine Rolle, ob diese Threads zum gleichen Prozess gehören oder zu einem anderen. Ein blockierter Thread bekommen den Zustand blocked oder waiting. Threads in diesem Zustand können nicht ausgeführt werden. Falls ein Prozeß nur blockierte Threads besitzt, gilt er selbst als blockiert. Sobald die belegte Ressource frei wird, hat der blockierte Thread die Chance wieder ready zu werden. Während der normalen Arbeit wechseln Prozesse (durch ihre Threads) also zwischen den Zuständen ready, running und blocked.

Sollte kein gültiger Thread in einem Prozess vorhanden sein, nimmt der Prozess den Zustand dead an. Prozesse in diesem Zustand haben ihre Arbeit getan und warten nur noch auf ihre Entfernung aus dem System und die Freigabe der von ihnen belegten Ressourcen.