Prozessverwaltung

Prozesskontext

Prozess ist Programm in Ausführung. Prozesskontext hat Informationen, die Prozess bei Ausführung auf CPU benötigt.


Prozess-Kontextwechsel auf CPU sind alle Tätigkeiten, um von auf CPU aktiven Prozess A auf Prozess B zu kommen

Es ist leicht verständlich, dass jeder Kontextwechsel eine gewisse Zeit für seine Durchführung beansprucht.

Prozesse erzeugen

Jeder Prozess erhält zur Unterscheidung und Verwaltung direkt bei seiner Erzeugung eine eindeutige Prozess-ID


Fork - Linux

image-1661150458823.png


CreateProcess - Windows
1. beginnt mit dem Öffnen der EXE-Datei.
2. erstellt notwendige Verwaltungsobjekte.
3. erstellt notwendige Verwaltungsobjekte.
4. informiert das Windows-Subsystem über den hier neu erstellten Prozess.
5. leitet die Ausführung des neu erstellten Prozesses ein.
6. nimmt alle abschließenden Initialisierungen vor.

Prozesskontrollblock

In Prozesskontrollblock fasst das Betriebssystem alle zu einem einzelnen Prozess gehörenden Informationen zusammen.

Windows

jeder unter Windows erzeugter Prozess wird durch eine Instanz der Datenstruktur EPROCESS repräsentiert

Linux

die Deklaration läuft über die Datenstruktur task_struct

Prozesstabelle

In der Prozesstabelle fasst das Betriebssystem alle Informationen aller erzeugter Prozesse zusammen. In der Praxis kann die Prozesstabelle ganz einfach als Liste aller Prozesskontrollblöcke realisiert werden.

image-1661155896048.png

Prozesszustände

Wird ein Prozess innerhalb eines Betriebssystems erzeugt, so bedeutet dies nicht, dass er auch sofort auf der CPU ausgeführt wird.

image-1661156084172.png

Prozessverwaltung

→ Eine der Aufgaben eines Betriebssystems ist ja die Verwaltung der erzeugten Prozesse
→ Dabei kommen Prozesskontrollblock und Prozesstabelle zum Einsatz.

Prozessverwaltung aus Admin-Sicht unter Windowsimage-1664738505389.png
→ Auch viele Informationen aus dem Prozesskontrollblock eines Prozesses werden hier zur Laufzeit des Prozesses sichtbar.

Prozessverwaltung aus Admin-Sicht unter Linux
→ auf Kommandozeile gibt es Programme, womit Administrator Aufschluss über die aktuell gestarteten Prozesse bekommt.
→ ps | pstree | top | htop

Threads

Thread oder Leichtgewichtigen Prozess ist Teil eines Prozesses, der einen unabhängigen Kontrollfluss repräsentiert.

BEISPIEL

Wenn ein Prozess nur einen Thread besitzt, ist dieser betrachtete Prozess praktisch gleichzusetzen mit seinem Thread.


Bei Thread-Kontextwechsel auf der CPU wird aktiver Thread A durch einen anderen Thread B ersetzt.


Vorteile Nachteil
  • Thread-Kontextwechsel leichter als Prozess-Kontextwechsel.
  • Threads eines Prozesses haben Zugriff auf alle Betriebsmittel, welche Prozess zugeordnet sind. 
  • Der Anwendungsprogrammierer kann die Funktionalität der Gesamtanwendung in unterschiedliche Threads aufteilen, welche jeder für sich einfacher zu implementieren ist. 
  • Threads eines Prozesses haben Zugriff auf Betriebsmittel, welche Prozess zugeordnet sind. 
  • Anwendungsprogrammierer müssen über Kenntnisse bei der Programmierung von Threads verfügen.

Scheduling

Beim Scheduling geht es um die Zuteilung des Betriebsmittels CPU zu den einzelnen Prozessen.

Unter Scheduling versteht man die Tätigkeit des Aufteilens der verfügbaren Prozessorzeit auf alle Prozesse.

Unter Scheduler  versteht man den Teil des Betriebssystems, welcher die Scheduling-Tätigkeit durchführt. Er ist zuständig zu entscheiden, welcher Prozess als nächstes die CPU bekommt. Umsetzung dieser Entscheidung obliegt dem Dispatcher.

Dispatcher entzieht bei Kontextwechsel dem aktiven Prozess die CPU, um sie dem nächsten Prozess zuzuteilen.

Kontextwechsel.jpg

Ziele: Möglichst viele Prozesse werden in  kurzer Zeit abgearbeitet.
Effizienz: zur Verfügung stehenden Ressourcen werden  ausgelastet.
Fairness: Die Ressourcen werden den Prozessen gerecht zugeteilt, das heißt, kein Prozess wird dauerhaft vernachlässigt.

Scheduling-Verfahren

image-1661765719508.png

First Come First Serve (FCFS)
arbeitet Prozesse in  Reihenfolge ihres Starts ab. Zuerst erzeugter Prozess darf auch als erstes in den Zustand Rechnend wechseln. Während Rechenzeit kann Prozess durch  Interrupt unterbrochen werden. Direkt nach Interrupt setzt er  Arbeit auf der CPU fort.

Shortest Job First (kurz: SJF): Von allen  Prozessen auf  System bekommt derjenige als erstes die CPU mit der kürzesten Laufzeit 

image-1661771489243.png

Shortest Remaining Time Next (kurz: SRTN)
ist eine Abwandlung des SJF-Verfahrens. Hierbei bekommt immer derjenige Prozess die CPU, welcher die kürzeste Restlaufzeit besitzt. Wenn Prozess A(5) aus Blocked hinaus kommt, kommt er vor Prozess B(8) wieder in Running, wenn Prozess C(6) von Running in Blocked wechselt. 

Round Robin (RR)
teilt die  zur Verfügung stehende CPU-Zeit in kleine Zeitscheiben. Prozesse werden in eine initiale Reihenfolge gebracht und der erste Prozess bekommt die CPU, er darf diese genau bis zum Ablauf seines Zeit-Quantums nutzen, danach in der Reihenfolge.

Priority Scheduling (kurz: PS)
Jedem Prozess wird eine Priorität zugewiesen. Der Prozess mit der höchsten Priorität bekommt als erstes die CPU.

Synchronisation

Bei der Synchronisation geht es um Mechanismen zur Vermeidung von Problemen, die bei der nebenläufigen Ausführung von Prozessen oder Threads in Verbindung mit gemeinsam genutzten Betriebsmitteln entstehen können.

Nebenläufigkeit ist quasi-parallele Ausführung von Befehlen mehrerer Prozesse oder Threads mit Kontextwechsel auf CPU.

Beim Race Conditions nutzen zwei oder mehr Prozesse ein oder mehrere Betriebsmittel gemeinsam, wobei das Ergebnis der Ausführung von der zeitlichen Reihenfolge der Zugriffe der Prozesse oder Threads auf das Betriebsmittel abhängt.

kritischer Abschnitt sind Programmteile, die während Ausführung auf der CPU nicht durch kritische Abschnitte anderer Prozesse oder Threads unterbrochen werden dürfen, sofern Prozesse auf gemeinsam genutzte Betriebsmittel zugreifen.


Aktives Warten - Prozesse und Threads synchronisieren

Unter aktivem Warten versteht man ständige Abfragen eines Sperrkennzeichens am Eingang eines kritischen Abschnitts.

public class Beispiel_Aktives_Warten {
  
 static int counter = 0;       // gemeinsam genutztes Betriebsmittel
 static int lock = 0;          // Sperrvariable
 
 public static class Thread_A extends Thread {
 	public void run() {
 		do_something();          // unkritisch
 		count_from_10();         // kritisch !!!
 		do_something_else();     // unkritisch
 	}
 	private void do_something() {
 		// unkritischer Abschnitt
 		System.out.println("Thread_A: unkritisch");	
 	}
 	private void count_from_10() {
 		// Vorsicht: kritischer Abschnitt!
 		while (lock == 1);       // wenn lock auf 1 ist, dann ist das Thread in der While-Schleife gefangen
 		lock = 1;				// wenn lock 0 war wird er hier auf 1 gesetzt und die Methode durchlaufen 
 		counter = 10;
 		counter++;
 		counter++;
 		System.out.println("A-Counter: " + counter);
 		lock = 0;		//die methode ist durchlaufen, auch wenn zwischen durch ein anderer 
 	}					//Thread dran war, ab hier kann ein anderer Thread durchlaufen werden 
 	private void do_something_else() {
 		// unkritischer Abschnitt
 		System.out.println("Thread_A: wieder unkritisch");	
 	}
}
	
public static class Thread_B extends Thread {
 	public void run() {
 		System.out.println("Thread_B ist gestartet.");
 		while (lock == 1);       // Semikolon beachten!
 		lock = 1;
 		counter = 20;
 		counter++;
 		counter++;
 		System.out.println("B-Counter: " + counter);
 		lock = 0;		
 	}
}
 
public static void main(String[] args) {
 	Thread a = new Thread_A();
 	Thread b = new Thread_B();
 	a.start();
 	b.start();
}
 
}

10: TSL 25          ; Hier passieren zwei Dinge als atomare Aktion:                    
		            ; --> Wert aus Speicherzelle 25 in Akkumulator kopieren                    
                    ; --> Zahl 1 in Speicherzelle 25 schreiben (setze lock=1)
11: EQUAL #0        ; Prüfe: Ist ACC == 0? (Eigentlich: ist lock == 0?)
12: JUMP 10         ; Prüfung ergab FALSE
13: ...             ; Prüfung ergab TRUE

Semaphore

Datenstruktur, welche ganzzahligen Zähler, Warteschlange bereitstellt und zwei atomare Operationen P() und V() definiert.


ein binären Semaphor ist ein Semaphor, dessen ganzzahliger Zähler nur die Werte 0 oder 1 annehmen kann.

  1. Mutex ist ein binären Semaphor, der mit einem wechselseitigen Ausschluss arbeitet und das aktive Warten ersetzt
    • Wenn ein Thread in kritischen Abschnitt befindet, darf andere Thread nicht in seinen kritischen Abschnitt eintreten
    • Reihenfolgedurchsetzung ist dabei sehr wichtig: Erst wenn erste Prozess Zugriff erledigt hat, darf der zweite
  2. Zählsemaphor ist ein Semaphor, der den Zugriff auf eine begrenzte Anzahl eines Betriebsmittels regelt.
    • Der Zugriff auf das Betriebsmittel stellt deshalb einen kritischen Abschnitt dar und muss geschützt werden.
    • Erzeuger- / Verbraucherproblem: Erzeuger erzeugt etwas, was Verbraucher verbraucht. Natürlich kann Verbraucher erst etwas verbrauchen, wenn zuvor Erzeuger etwas erzeugt hat. Erzeuger kann nur soviel erzeugen, bis alle Lagerplätze für Erzeugnis belegt sind. Dann muss Verbraucher wieder verbrauchen, bis Erzeuger wieder etwas erzeugen kann.

Ein Semaphor hat keinen ungünstigen Moment, weil die P() Methode atomar ist!

Deadlocks

Eine Menge von Prozessen befindet sich in einem Deadlock-Zustand, wenn jeder Prozess aus der Menge auf ein Ereignis wartet, das nur ein anderer Prozess aus der Menge auslösen kann.

Wenn sich mehrere Prozesse in Deadlock-Zustand befinden, so sagt man auch vereinfachend: Es ist ein Deadlock aufgetreten. image-1662922977765.png

Vier Bedinnungen damit ein Deaklock auftritt:

  1. Mutual exclusion condition: Eine Ressource steht einem Prozess nur exklusiv zur Verfügung
  2. Wait for condition: Prozesse warten und behalten dabei Kontrolle über bereits Ressourcen 
  3. No preemption condition: Ressourcen können Prozess nicht entrissen werden.
  4. Circular wait condition: Es gibt eine zyklische Kette von Prozessen

image-1662923775801.pngPrinzip des ersten Kontos

 


Deadlocks ignorieren
"Es gibt keine Deadlocks, weil ich daran glaube, dass es keine Deadlocks gibt!", sagt das Betriebssystem.
Zum Ignorieren von Deadlocks kommt in Betriebssystemen üblicherweise der Vogel-Strauß-Algorithmus zum Einsatz.

Deadlocks vermeiden
Ein Betriebssystem könnte von vorneherein so konstruiert werden, dass Deadlocks gar nicht möglich sind.

Verhinderung von Deadlocks 
Prozess nur dann weitere Ressource zuzusprechen, wenn sichergestellt ist, dass in der Zukunft kein Deadlock entstehen kann

Allgemein ist davon auszugehen, dass die Erkennung, Vermeidung oder Verhinderung von Deadlocks sehr aufwendig ist. Eine ausnahmlose Abdeckung aller denkbarer Fälle scheint nahezu unmöglich.

Interprozesskommunikation

Bei der Interprozesskommunikation geht es um den Austausch von Informationen zwischen zwei (oder mehr) Prozessen bzw. Threads. Damit alle Beteiligten die ausgetauschten Informationen in gleicher Weise verstehen können, sind bestimmte Regeln der Kommunikation einzuhalten, das sogenannte Protokoll

Zwei Threads kommunizieren über gemeinsame Variablen
→ Synchronisation Threads beim Zugriff auf gemeinsamen Datenbereiche wird erforderlich, da es zu kritischen Abläufen kommt

Zwei Prozesse kommunizieren über gemeinsame Speicherobjekte (Datein)
Prozess A erzeugt während Laufzeit Daten und speichert diese in einer Datei ab.
→ zweiter Prozess B liest Datei zu einem späteren Zeitpunkt ein und kann so die enthaltenen Informationen weiterverarbeiten.
→ sorgt Betriebssystem nur für eine Synchronisation beim gleichzeitigen Zugriff der beiden Prozesse auf die (z.B. über Semaphore).
→ Falls Prozess B Dateiinhalt ausliest, bevor Prozess A die Informationen hineingeschrieben hat, so ist nicht zu erwarten, dass Prozess B das erwartete Ergebnis berechnen kann

Zwei Prozesse kommunizieren über Shared Memory
Man spricht von Shared Memory, wenn Teil des Hauptspeichers gemeinsam mehreren Prozessen zur Verfügung gestellt wird

Zwei Prozesse kommunizieren über Pipes
Einweg-Kommunikationskanäle, die Prozess ermöglichen, Daten über das BS als Datenstrom an anderen Prozess zu übertragen

Zwei Prozesse kommunizieren über Sockets
Sockets sind eine vom Betriebssystem bereitgestellte Kommunikationsmöglichkeit über TCP