Auf einem typischen Desktop-System laufen rund 100 bis 200 unterschiedliche Prozesse. Selbst ein einfacher Linux-Server mit Apache als Webserver, Postfix als E-Mail-Server und einigen weiteren Diensten startet 50 bis 100 Prozesse. Deren friedliches Miteinander funktioniert nur aufgrund der ausgeklügelten Mechanismen und Algorithmen, mit deren Hilfe der Kernel den Prozessen Ressourcen zuteilt oder entzieht.
Der Linux-Kernel verfügt über einen leistungsfähigen Prozess-Scheduler und eine ausgereifte Speicherverwaltung, um gestarteten Prozessen Rechenzeit und Speicher zuzuteilen. Ein wählbarer IO-Scheduler bringt Zugriffe auf Massenspeicher in eine geeignete Reihenfolge. Ausgefeiltes Ressourcenmanagement regelt den Zugriff auf Hardwarekomponenten.
Am Anfang
Hat das BIOS den Bootloader und der Bootloader den Linux-Kernel gestartet, initialisiert dieser die zu diesem Zeitpunkt wesentliche Hardware und stößt dann den ersten Prozess namens Init an. Der Init-Prozess wiederum startet über ein komplexes System von Skripten weitere Prozesse, um abhängig vom eingestellten Runlevel einen bestimmten Zustand herzustellen [1]. Die Konfiguration dazu findet sich gewöhnlich in der Datei /etc/inittab auf der Festplatte. Der Einsatz der Runlevel variiert von Distribution zu Distribution. Gewöhnlich dokumentiert die Datei inittab die Details.
Üblicherweise stehen die Runlevel 2 bis 5 für verschiedene Mehrbenutzer-Umgebungen mit oder ohne Netzwerk und grafischer Oberfläche. Runlevel 1 bleibt für den Einzelbenutzer-Betrieb reserviert, etwa für Wartungsarbeiten am System. Runlevel 0 dient gewöhnlich dem Anhalten und 6 dem Neustart des Systems.
Jede Zeile besteht aus vier mit Doppelpunkten voneinander getrennten Spalten (Listing 1, Zeile 9 bis 15). Die erste Spalte enthält einen beliebigen Namen für den Eintrag. In Spalte zwei folgen die Runlevel, in denen Init die in Spalte 3 angegebene Aktion ausführt. Bei der Aktion wait startet Init den in Spalte vier angegebenen Befehl und wartet auf dessen Ende.
# The default runlevel. id:2:initdefault: # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # What to do when CTRL-ALT-DEL is pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now 1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6
Bei der Aktion respawn (Listing 1, Zeile 20 bis 25) startet Init den Befehl aus Spalte 4 hingegen immer wieder neu, wenn Sie diesen beenden. Mit der Aktion ctrlaltdel (Zeile 18) geben Sie an, was beim Drücken von [Strg]+[Alt]+[Entf] geschieht – in der Regel ein Neustart des Systems. Das funktioniert jedoch normalerweise nur im Textmodus, da der X-Server die Tastenkombination abfängt.
Die Aktion respawn kommt bei den getty-Prozessen zum Einsatz, die die Textkonsolen bereit stellen. Zwischen diesen schalten Sie üblicherweise mit [Alt]+[F1] bis [Alt]+[F6] um. Die Tastenkombination [Alt]+[F7] ist üblicherweise für X11 basierte grafische Oberfläche reserviert, weitere Sitzungen folgen ab [Alt]+[F8]. Möchten Sie von der grafischen Oberfläche aus wechseln, drücken Sie zusätzlich [Strg].
Jedes Terminal hat ein TTY, dessen Gerätedatei (zum Beispiel /dev/tty1) Sie mit dem Befehl tty ermitteln. Bei einer Shell via SSH oder in einem grafischen Terminal-Client wie Xterm, Konsole von KDE oder Terminal von Gnome kommt ein Pseudoterminal wie /dev/pts/1 zum Einsatz.
Die Zeile mit der Aktion initdefault (Listing 1, Zeile 2) gibt den Standard-Runlevel nach dem Booten an. Dort sollte aus naheliegendem Grund weder der Runlevel 0 (Halt) noch der Runlevel 6 (Reboot) stehen. Für jeden der Runlevel startet Init im Beispiel das Skript /etc/init.d/rc mit dem entsprechenden Runlevel als Argument. Das Skript wiederum stößt über ein System mit symbolischen Verweisen weitere Skripte an, die konkrete Dienste in Gang setzen oder stoppen. Die symbolischen Verweise befinden sich bei Debian-basierten Distributionen in den Verzeichnissen /etc/rc0.d bis /etc/rc6.d sowie /etc/rcS.d und bei Suse in /etc/init.d/rc0.d und /etc/init.d/rc6.d sowie /etc/init.d/rcS.d.
Die Namen der Verweise folgen einem Schema: Ein S als erstes Zeichen deutet darauf hin, dass das entsprechende Init-Skript mit dem Argument start losrennt. Bei einem K hingegen kommt ein stop als Argument zum Einsatz. Die darauf folgende, üblicherweise zweistellige Zahl definiert die Reihenfolge, in der die Skripte starten. Mit ls -l verschaffen Sie sich einen groben Überblick in den Verzeichnissen.
Der Befehl who -r zeigt den aktuellen Runlevel, mit init Runlevel
wechseln Sie in einen anderen. Speichern Sie jedoch alle wichtigen Daten ab, bevor Sie das ausprobieren. Alternativ halten Sie das System mit shutdown now oder halt an, mit shutdown -r now oder reboot starten Sie es neu. Statt now akzeptiert der Befehl shutdown auch eine andere Zeitangabe.
Was geht?
Einen Überblick darüber, welcher Prozess welche anderen Prozesse startet, verschaffen Sie sich mit Pstree [2]. Der Befehl zeigt in einer Baumstruktur die Kind-Prozesse von Init an. Viele KDE-Anwendungen hängen zum Beispiel von Kdeinit ab, einem Mechanismus, der die Startzeit von KDE-Anwendungen verkürzt (Abbildung 1). Auch der Linux-Kernel startet eigene Prozesse. Dazu verwendet er die Funktion Kthread, die alle weiteren Aktionen anschiebt.
Jeder Prozess hat eine eindeutige Nummer, die Prozess-ID (PID). Mit pstree -p zeigt das Tool diese Information zusätzlich an. Sie erfahren die Prozess-ID eines bestimmten Prozesses auch über die Befehle pidof oder pgrep. Laufen mehrere Prozesse mit gleichen Namen, liefern beide die Nummern aller Prozesse zurück. Übergeben Sie Pstree eine Prozess-ID als Argument, so baut es die Baumstruktur von diesem Prozess aus auf:
$ pstree $(pidof kdeinit) $ pstree $(pidof kthread)
Eine Liste aller Prozesse erhalten Sie auch mit dem Befehl ps. Gängige Optionen sind u für die Angabe des Benutzers, mit dessen Rechten ein Prozess läuft, x für die Ausgabe von Prozessen ohne TTYs (in der Regel Prozesse der grafischen Oberfläche) oder a zum Anzeigen der Prozesse anderer Benutzer. Die Option f präsentiert eine Baumstruktur ähnlich wie bei Pstree, mit e erfahren Sie die Umgebungsvariablen jedes Prozesses. Die Kombinationen ps aux und ps ef kommen zum Beispiel sehr häufig zum Einsatz.



