Eine wichtige Aufgabe eines Betriebssystems ist die Zuteilung von Ressourcen an die Prozesse. Dies betrifft sowohl die Festplatte, wie auch das Netzwerk, die CPU und andere Hardware-Einheiten, die nur in einem begrenzten Umfang zur Verfügung stehen, aber von mehreren Prozessen genutzt werden wollen. Dies mag zu ruhigen Zeiten geschehen, wo weniger Prozesse arbeiten wollen, als es Ressourcen gibt, aber auch in anspruchsvollen Zeiten, wo das Verhältnis umgekehrt ist.

Um die Zuteilung der CPU kümmert sich bei Linux der Process Scheduler, der verschiedene Informationen zu einem Prozess nutzt, um ihn sinnvoll einer CPU zuzuordnen, denn in modernen Computern besteht eine CPU aus mehreren Kernen, die selbst wiederum mehrere Threads verarbeiten können; siehe den Befehl lscpu. Dabei ist der RAM-Zugriff eine relevante Größe bei der Verarbeitungsgeschwindigkeit, der durch Caches (L1, L2, L3) in mehreren Kaskaden optimiert wird. Da die unterschiedlichen Cache-Stufen und RAM-Abschnitte ungleichmäßig von den einzelnen CPUs erreichbar sind (NUMA, non-uniform memory access), muss der Scheduler auch berücksichtigen, ob ein verfügbarer CPU-Kern gut auf den RAM des Prozesses zugreifen kann.

Neben diesen physikalischen Randparametern gibt es auch noch die logische Strukturierung der Prozesse untereinander, denn der Administrator kann die Prozesse mit dem Befehl chrt in Dringlichkeitsstufen einordnen:

  1. Stop: nur kernelintern für die Prozesse migration/N verwendet, um eine CPU für Verwaltungsaufgaben zu übernehmen
  2. Deadline: für Echtzeitbehandlung von Prozessen, um zu garantieren, dass Prozesse zu einem zuvor bestimmten Zeitpunkt die CPU nutzen können; z. B. für Video- oder Musikwiedergabe
  3. POSIX realtime: um Prozessen möglichst lang (SCHED_FIFO) oder sehr häufig (SCHED_RR) die CPU zuzuteilen
  4. CFS (completely fair scheduling): für die durchschnittlichen Prozesse mit den Unterteilungen:
    1. other: Standardklasse für Prozesse, anhand des nice-Werts wird eine Priorität berechnet
    2. batch: rechenintensive Hintergrundprozesse, die die CPU für einen längeren Zeitabschnitt nutzen möchten; z. B. Cron-Jobs
    3. idle: Prozesse mit der niedrigsten Priorität, die nur ausgeführt werden, wenn kein anderer Prozess die CPU benötigt; z. B. Indizierung von Dateien für eine Suchdatenbank
  5. Idle: nur kernelintern, um eine CPU schlafen zu legen

Wenn der laufende Prozess einer CPU zum Stehen kommt, weil er zum Beispiel auf eine andere Ressource wie die Festplatte, den RAM oder einen Zeitgeber (Timer) warten muss, sucht der Scheduler in jeder der obigen Stufen nach einem neuen Kandidaten für die CPU und wird gemäß den oben beschriebenen Kriterien einen neuen Prozess auswählen.

Weiteres

  • der Artikel bei LWN auf dem der Großteil der obigen Informationen beruht: Fixing SCHED_IDLE
  • bei atop kann man sich die Informationen mit s (scheduler) ansehen oder mit ps lax -c
  • ich habe in meiner .zshrc diverse Aliase mit chrt --batch 0 … definiert, u. a. für make, cargo, apt, dpkg-buildpackage