Prozessmanagement

KAPITEL 03 · BETRIEBSSYSTEME

Prozessmanagement

Das Herzstück jedes Betriebssystems – wie Prozesse erzeugt, geplant, synchronisiert und verwaltet werden. Lernen Sie Scheduling-Algorithmen, IPC, Threads und Deadlocks kennen.

Prozesszustände Scheduling IPC Synchronisation

Inhaltsverzeichnis

Schnellübersicht

Auf dieser Seite lernen Sie alles über Prozessmanagement im Betriebssystem:

  • Definition: Was ist ein Prozess? Unterschied zu Programm
  • Prozesszustände: New, Ready, Running, Waiting, Terminated
  • Process Control Block (PCB): Verwaltungsinformationen
  • Kontextwechsel: Wie das OS zwischen Prozessen wechselt
  • Scheduling-Algorithmen: FCFS, SJF, Round Robin, Priority
  • Inter-Prozess-Kommunikation (IPC): Pipes, Shared Memory, Sockets
  • Synchronisation: Mutex, Semaphore, Monitore
  • Deadlocks: Bedingungen, Vermeidung, Erkennung
  • Threads: Unterschied zu Prozessen
  • FAQ: Häufige Fragen zum Prozessmanagement

1. Was ist ein Prozess?

Definition

Ein Prozess ist ein Programm in Ausführung. Während ein Programm eine passive Datei auf der Festplatte ist (statisch), ist ein Prozess eine aktive Einheit mit eigenem Speicherzustand, Programmzähler, Registern und Ressourcen (dynamisch).

Das Betriebssystem verwaltet alle laufenden Prozesse und sorgt dafür, dass sie fair und effizient die CPU-Ressourcen nutzen. Ein einzelnes Programm kann mehrere Prozesse erzeugen (z.B. öffnet ein Browser mehrere Tabs als separate Prozesse).

Beispiel: Wenn Sie Firefox starten, wird die Programmdatei firefox.exe von der Festplatte in den Arbeitsspeicher geladen und als Prozess ausgeführt. Das Betriebssystem weist ihm CPU-Zeit, Speicher und andere Ressourcen zu.

Prozess vs. Programm

  • Programm: Passive Datei (statisch), liegt auf Festplatte
  • Prozess: Aktive Ausführung (dynamisch), hat eigenen Speicherzustand
  • Ein Programm kann mehrere Prozesse erzeugen
  • Ein Prozess kann mehrere Threads enthalten

2. Prozesszustände

Ein Prozess durchläuft während seiner Lebensdauer verschiedene Zustände. Das 5-Zustände-Modell ist der Standard:

5-Zustände-Modell

New

Prozess wird erzeugt, PCB wird angelegt

Ready

Bereit zur Ausführung, wartet auf CPU

Running

Befehle werden auf CPU ausgeführt

Waiting

Wartet auf Ereignis (I/O, Signal)

Terminated

Prozess beendet, Ressourcen freigegeben

Zustandsübergänge

  • New → Ready: Prozess wurde erzeugt und ist bereit
  • Ready → Running: Scheduler weist Prozess CPU zu (Dispatch)
  • Running → Ready: Zeitquantum abgelaufen oder Preemption
  • Running → Waiting: Prozess wartet auf I/O oder Ereignis
  • Waiting → Ready: Ereignis eingetreten, Prozess wieder bereit
  • Running → Terminated: Prozess beendet sich selbst oder wird abgebrochen

3. Process Control Block (PCB)

Jeder Prozess wird durch einen Process Control Block (PCB) repräsentiert – eine Datenstruktur im Betriebssystem-Kernel, die alle wichtigen Informationen über den Prozess speichert.

Inhalt eines PCB

Prozess-ID (PID)

Eindeutige Nummer zur Identifikation des Prozesses (z.B. PID 1234)

Prozesszustand

Aktueller Zustand: new, ready, running, waiting, terminated

Programmzähler (PC)

Adresse des nächsten auszuführenden Befehls

CPU-Register

Gesicherte Registerinhalte (Akkumulator, Stack Pointer, etc.)

Speicherverwaltung

Page Table, Segment Table, Base/Limit Register

Geöffnete Dateien

Liste aller vom Prozess geöffneten Dateien und I/O-Geräte

Besitzinformationen

Benutzer-ID (UID), Gruppen-ID (GID), Elternprozess (PPID)

Scheduling-Info

Priorität, Queue-Pointer, Zeitquantum, CPU-Zeit verbraucht

Warum ist der PCB wichtig?

Der PCB ermöglicht dem Betriebssystem, jederzeit den Zustand eines Prozesses zu speichern und wiederherzustellen. Bei einem Kontextwechsel werden alle Registerinhalte im PCB des aktuellen Prozesses gesichert und die des neuen Prozesses geladen – so kann der Prozess später exakt dort weitermachen, wo er aufgehört hat.

4. Kontextwechsel (Context Switch)

Ein Kontextwechsel ist der Vorgang, bei dem die CPU von einem Prozess zu einem anderen wechselt. Dies ist eine der wichtigsten (und teuersten) Operationen des Betriebssystems.

Ablauf eines Kontextwechsels

1
Interrupt/Trap

Timer-Interrupt, I/O-Interrupt oder System Call unterbricht aktuellen Prozess

2
Register sichern

Alle CPU-Register des aktuellen Prozesses werden in dessen PCB gespeichert

3
PCB aktualisieren

Zustand des alten Prozesses wird auf "ready" oder "waiting" gesetzt

4
Neuen Prozess wählen

Scheduler wählt nächsten Prozess aus Ready-Queue

5
Register laden

Registerinhalte aus dem PCB des neuen Prozesses werden in die CPU geladen

6
Weiter ausführen

CPU setzt Ausführung beim gespeicherten Programmzähler fort

Kosten eines Kontextwechsels

  • Dauer: Typisch 1-10 Mikrosekunden (reine Overhead-Zeit)
  • Kein produktiver Work: Während des Wechsels wird nichts "sinnvolles" berechnet
  • Cache-Verlust: CPU-Cache muss oft neu geladen werden (Cache Miss)
  • TLB-Flush: Translation Lookaside Buffer muss neu gefüllt werden
  • Optimierung: Moderne OS minimieren Kontextwechsel durch intelligente Scheduling-Strategien

5. Scheduling-Algorithmen

Der Scheduler entscheidet, welcher Prozess aus der Ready-Queue als nächstes die CPU erhält. Es gibt verschiedene Algorithmen mit unterschiedlichen Stärken und Schwächen.

FCFS

First-Come, First-Served

Prozesse werden in der Reihenfolge ihrer Ankunft ausgeführt – wie an einer Supermarktkasse.

  • Einfach zu implementieren
  • Fair (keine Bevorzugung)
  • Convoy-Effekt (kurze warten auf lange)
  • Nicht-preemptiv
Einsatz: Batch-Systeme, wo Fairness wichtiger ist als Response-Time

SJF / SRT

Shortest Job First

Der Prozess mit der kürzesten Burst-Zeit wird zuerst ausgeführt. Optimal für minimale Wartezeit.

  • Optimal (minimale avg. Wartezeit)
  • Gut für interaktive Systeme
  • Starvation für lange Jobs
  • Burst-Zeit schwer vorhersagbar
Einsatz: Batch-Systeme mit bekannten Laufzeiten

Round Robin

Zeitquanten-basiert

Jeder Prozess bekommt ein festes Zeitquantum (z.B. 10ms). Nach Ablauf wird er hinten angestellt.

  • Fair (alle bekommen CPU-Zeit)
  • Gut für Time-Sharing
  • Responsive für User
  • Höherer Kontextwechsel-Overhead
Einsatz: Desktop-OS, interaktive Systeme (Standard in Linux/Windows)

Priority Scheduling

Prioritätsbasiert

Jeder Prozess hat eine Priorität. Der Prozess mit der höchsten Priorität wird zuerst ausgeführt.

  • Wichtige Prozesse bevorzugt
  • Gut für Echtzeitsysteme
  • Starvation für niedrige Priorität
  • Aging nötig (Priorität steigt mit Zeit)
Einsatz: Echtzeitsysteme, Server mit unterschiedlichen Workloads

Multilevel Queue

Mehrere Warteschlangen

Ready-Queue wird in mehrere separate Queues aufgeteilt (z.B. System, Interactive, Batch).

  • Unterschiedliche Policies pro Queue
  • Gute Trennung der Workloads
  • Starvation möglich
  • Komplexer zu konfigurieren
Einsatz: Enterprise-Server mit verschiedenen Prozess-Typen

Multilevel Feedback Queue

Adaptives Scheduling

Prozesse können zwischen Queues wechseln – kurze Jobs steigen auf, lange sinken ab.

  • Sehr flexibel und anpassungsfähig
  • Kombiniert Vorteile aller Algorithmen
  • Verhindert Starvation
  • Sehr komplex
Einsatz: Moderne Desktop-OS (Linux CFS, Windows)
Algorithmus Preemptiv Starvation Overhead Typischer Einsatz
FCFS Nein Nein Niedrig Batch-Systeme
SJF Optional Ja (lang) Mittel Batch, kurze Jobs
Round Robin Ja Nein Mittel Desktop, Time-Sharing
Priority Optional Ja (niedrig) Niedrig Echtzeit, Server
MLQ Optional Möglich Mittel Enterprise-Server
MLFQ Ja Nein Hoch Moderne Desktop-OS

6. Inter-Prozess-Kommunikation (IPC)

Prozesse sind isoliert und können nicht direkt auf den Speicher anderer Prozesse zugreifen. Für den Austausch von Daten und Synchronisation gibt es verschiedene IPC-Mechanismen:

Pipes

Einweg-Datenkanal zwischen verwandten Prozessen (Eltern-Kind). Einfach, aber unidirektional.

# Unnamed Pipe (Shell) ls | grep "txt" # Named Pipe (FIFO) mkfifo mypipe echo "data" > mypipe

Shared Memory

Schnellste IPC – mehrere Prozesse teilen sich einen Speicherbereich. Erfordert Synchronisation!

// POSIX Shared Memory int fd = shm_open("/myshm", O_CREAT | O_RDWR, 0666); void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

Message Queues

Strukturierte Nachrichten in einer Queue. Prozesse können asynchron senden und empfangen.

// POSIX Message Queue mqd_t mq = mq_open("/myqueue", O_CREAT | O_WRONLY, 0644, NULL); mq_send(mq, buffer, size, priority);

Sockets

Kommunikation über Netzwerk oder lokal (Unix Domain Sockets). Für Client-Server-Architekturen.

// TCP Socket int sock = socket(AF_INET, SOCK_STREAM, 0); connect(sock, &addr, sizeof(addr)); send(sock, data, len, 0);

Signals

Asynchrone Benachrichtigungen (z.B. SIGINT, SIGTERM). Für einfache Ereignisse, keine Daten.

# Signale senden kill -SIGTERM 1234 kill -SIGKILL 1234 # Signal Handler in C signal(SIGINT, handler);

IPC-Mechanismen im Vergleich

  • Shared Memory: Schnellste, aber komplex (Synchronisation nötig)
  • Message Queues: Strukturiert, einfach zu nutzen, etwas langsamer
  • Pipes: Einfach, aber nur zwischen verwandten Prozessen
  • Sockets: Flexibel (lokal + Netzwerk), Overhead durch Protokoll-Stack
  • Signals: Nur für Ereignisse, keine Datenübertragung

7. Synchronisation & Deadlocks

Wenn mehrere Prozesse auf gemeinsame Ressourcen zugreifen, müssen sie synchronisiert werden, um Race Conditions und Deadlocks zu vermeiden.

Synchronisationsmechanismen

Mutex (Mutual Exclusion)

Ein Lock, der sicherstellt, dass nur ein Prozess gleichzeitig auf eine Ressource zugreift. Einfachstes Synchronisationsmittel.

pthread_mutex_t mutex; pthread_mutex_lock(&mutex); // Kritischer Bereich pthread_mutex_unlock(&mutex);
Semaphore

Zähler-basierter Mechanismus. Erlaubt N Prozessen gleichzeitigen Zugriff (Counting Semaphore) oder nur einem (Binary Semaphore = Mutex).

sem_t sem; sem_init(&sem, 0, 3); // 3 erlaubt sem_wait(&sem); // P() / down() // Kritischer Bereich sem_post(&sem); // V() / up()
Monitor

Höheres Konzept: Kapselt Daten und Synchronisation. Nur ein Prozess kann Monitor gleichzeitig betreten. In Java/C# integriert.

// Java synchronized public synchronized void deposit() { balance += amount; } // C# lock lock (this) { balance += amount; }
Deadlock

Zwei oder mehr Prozesse warten gegenseitig auf Ressourcen – keiner kann fortfahren. Muss vermieden oder erkannt werden.

// 4 Deadlock-Bedingungen (Coffman): 1. Mutual Exclusion 2. Hold and Wait 3. No Preemption 4. Circular Wait

Umgang mit Deadlocks

  • Ignorieren: Ostrich-Algorithmus (Linux/Windows machen das oft)
  • Vermeidung: Banker's Algorithmus (Dijkstra) – prüft vor jeder Zuweisung
  • Erkennung: Resource-Allocation-Graph analysieren, Deadlock erkennen und beheben
  • Verhinderung: Eine der 4 Coffman-Bedingungen brechen (schwierig)

8. Threads vs. Prozesse

Threads sind "leichtgewichtige Prozesse" – sie teilen sich den Speicher eines Prozesses, haben aber eigene Register und Stack.

Prozess

  • Eigener, isolierter Speicherbereich
  • Eigene PCB, Ressourcen, File Descriptors
  • Aufwendige Erstellung (fork/exec)
  • Kontextwechsel teuer (Cache-Flush)
  • Robust: Ein Crash betrifft nur einen Prozess
  • IPC nötig für Kommunikation
VS

Thread

  • Teilt sich Speicher mit anderen Threads
  • Eigener Stack, Register, Thread-ID
  • Leichtgewichtige Erstellung (pthread)
  • Kontextwechsel günstiger
  • Gefährlich: Ein Crash tötet alle Threads
  • Direkte Kommunikation über Shared Memory

Wann was verwenden?

  • Prozesse: Wenn Isolation und Stabilität wichtig sind (z.B. Web-Browser-Tabs)
  • Threads: Wenn Performance und Shared State wichtig sind (z.B. Web-Server, Datenbanken)
  • Hybrid: Moderne Systeme nutzen beides – z.B. Browser mit Multi-Process + Multi-Thread
  • Async/await: Moderne Alternative zu Threads für I/O-intensive Tasks (Node.js, Python asyncio)

9. FAQ – Häufige Fragen & Antworten

Häufige Fragen zum Prozessmanagement

Was ist der Unterschied zwischen einem Prozess und einem Thread?

Prozess: Eigenständiges Programm in Ausführung mit isoliertem Speicher. Robust, aber ressourcenintensiv.

Thread: "Leichtgewichtiger Prozess" innerhalb eines Prozesses. Teilt sich Speicher mit anderen Threads desselben Prozesses. Schneller, aber weniger stabil.

Analogie: Ein Prozess ist wie ein Haus, Threads sind die Bewohner. Jeder Bewohner hat sein eigenes Zimmer (Stack), teilt sich aber Küche und Wohnzimmer (Shared Memory).

Warum ist Round Robin der Standard in Desktop-Betriebssystemen?

Round Robin ist ideal für Desktop-Systeme, weil:

  • Fairness: Jeder Prozess bekommt regelmäßig CPU-Zeit
  • Responsiveness: User-Input wird schnell beantwortet
  • Kein Starvation: Kein Prozess wird vernachlässigt
  • Einfach: Leicht zu implementieren und zu verstehen

Moderne Systeme verwenden oft Multilevel Feedback Queues, die Round Robin mit anderen Algorithmen kombinieren.

Was ist ein Deadlock und wie vermeide ich ihn?

Ein Deadlock tritt auf, wenn zwei oder mehr Prozesse gegenseitig auf Ressourcen warten, die der andere hält – keiner kann fortfahren.

4 Bedingungen (Coffman):

  • Mutual Exclusion (Ressource nicht teilbar)
  • Hold and Wait (Prozess hält Ressourcen und wartet auf weitere)
  • No Preemption (Ressourcen können nicht weggenommen werden)
  • Circular Wait (zyklische Wartekette)

Vermeidung: Eine der 4 Bedingungen brechen – z.B. alle benötigten Ressourcen auf einmal anfordern (bricht "Hold and Wait") oder Ressourcen mit Timeout anfordern.

Was ist der Convoy-Effekt bei FCFS?

Der Convoy-Effekt tritt bei FCFS auf, wenn ein langer Prozess (z.B. CPU-intensive Berechnung) viele kurze Prozesse blockiert.

Beispiel: Wenn Prozess A 100ms braucht und Prozesse B, C, D nur 10ms, müssen B, C, D trotzdem auf A warten. Die durchschnittliche Wartezeit steigt dramatisch.

Lösung: SJF oder Round Robin verwenden – kurze Prozesse werden bevorzugt oder bekommen regelmäßig CPU-Zeit.

Warum ist Shared Memory die schnellste IPC-Methode?

Shared Memory ist die schnellste IPC-Methode, weil:

  • Kein Kopieren: Daten werden nicht zwischen Prozessen kopiert
  • Direkter Zugriff: Prozesse greifen direkt auf denselben Speicher zu
  • Kein Kernel-Overhead: Keine System Calls für jeden Datentransfer

Nachteil: Erfordert Synchronisation (Mutex/Semaphore), sonst Race Conditions. Komplexer zu programmieren als Pipes oder Message Queues.

Was ist der Unterschied zwischen preemptivem und nicht-preemptivem Scheduling?

Preemptiv (verdrängend): Das OS kann einen laufenden Prozess unterbrechen und einem anderen Prozess die CPU geben (z.B. Round Robin, Priority mit Preemption).

Nicht-preemptiv: Ein Prozess behält die CPU, bis er sie freiwillig abgibt (z.B. FCFS, SJF non-preemptive).

Vorteil Preemptiv: Bessere Responsiveness, fairer.
Nachteil Preemptiv: Höherer Overhead durch häufige Kontextwechsel, Race Conditions möglich.

Was ist ein Zombie-Prozess und wie entsteht er?

Ein Zombie-Prozess ist ein Prozess, der beendet wurde, aber dessen Exit-Status noch nicht vom Elternprozess abgeholt wurde (via wait()).

Zustand: Der Prozess ist tot (keine CPU, kein Speicher), aber sein PCB-Eintrag bleibt in der Prozesstabelle, bis der Elternprozess den Status abholt.

Problem: Zu viele Zombies verbrauchen PID-Ressourcen. Lösung: Elternprozess muss wait() aufrufen oder SIGCHLD-Handler installieren.

Was ist ein Orphan-Prozess?

Ein Orphan-Prozess ist ein Prozess, dessen Elternprozess bereits beendet wurde, bevor der Kindprozess terminiert.

Lösung: Das Betriebssystem (init-System, z.B. systemd) adoptiert den Orphan und wird zu seinem neuen Elternprozess. Der init-Prozess holt automatisch den Exit-Status ab.

Beispiel: Daemon-Prozesse (Hintergrunddienste) werden oft absichtlich zu Orphans gemacht, damit sie unabhängig vom aufrufenden Terminal weiterlaufen.

Zusammenfassung

Die wichtigsten Punkte

  • Prozess: Programm in Ausführung mit eigenem Speicherzustand
  • 5 Zustände: New → Ready → Running → Waiting → Terminated
  • PCB: Datenstruktur mit allen Prozessinformationen (PID, Register, Zustand)
  • Kontextwechsel: Wechsel zwischen Prozessen – teuer, aber notwendig
  • Scheduling: FCFS, SJF, Round Robin, Priority, MLQ, MLFQ
  • IPC: Pipes, Shared Memory, Message Queues, Sockets, Signals
  • Synchronisation: Mutex, Semaphore, Monitor verhindern Race Conditions
  • Deadlock: 4 Coffman-Bedingungen – Vermeidung durch Banker's Algorithm
  • Threads: Leichtgewichtige Prozesse, teilen sich Speicher, schneller Kontextwechsel
  • Zombie/Orphan: Spezielle Prozesszustände mit eigenen Lösungen

Prozessmanagement in der Praxis

  • Linux: ps aux, top, htop zur Prozessüberwachung
  • Windows: Task-Manager, Process Explorer, tasklist
  • Programmierung: fork(), exec(), pthread_create()
  • Monitoring: Prometheus, Grafana, Nagios für Prozess-Metriken
  • Container: Docker, Kubernetes – isolierte Prozesse mit eigenen Namespaces

Weiterführende Themen

OS-Grundlagen

Grundlegende Konzepte von Betriebssystemen – Kernel, User Space, System Calls.

Zu OS-Grundlagen
Linux

Linux im Detail – Distributionen, Paketmanagement, Shell-Scripting.

Zu Linux
Terminal-Befehle

Wichtige Kommandozeilen-Befehle für Linux und Windows.

Zu Terminal-Befehlen
Dateisysteme

NTFS, ext4, APFS – wie Daten auf Speichermedien organisiert werden.

Zu Dateisystemen