std.sched
Scheduling & CPU-Affinität (WP-8): Steuert auf welchen CPUs ein Prozess oder Thread läuft (CPU-Pinning), liest und setzt den Nice-Wert (Priorität) und gibt die CPU freiwillig ab. Enthält Helfer zum Aufbau von cpu_set_t-Bitmasken für bis zu 1024 CPUs.
→ Standard Library · std.process_ext · std.thread
Konstanten
cpu_set_t
| Konstante | Wert | Beschreibung |
|---|---|---|
CPU_SET_SIZE | 128 | Größe einer cpu_set_t-Bitmap in Bytes (1024 CPUs) |
Prioritäts-Scope
| Konstante | Wert | Beschreibung |
|---|---|---|
PRIO_PROCESS | 0 | GetPriority/SetPriority operiert auf Prozess-ID |
PRIO_PGRP | 1 | Operiert auf Prozessgruppen-ID |
PRIO_USER | 2 | Operiert auf Benutzer-ID |
Funktionen
Scheduling
| Signatur | Beschreibung |
|---|---|
SchedYield(): int64 | Gibt die CPU freiwillig ab — der aktuelle Thread wird ans Ende der Run-Queue gestellt. Gibt immer 0 zurück |
CPU-Affinität
| Signatur | Beschreibung |
|---|---|
SchedSetAffinity(pid: int64, cpuMask: int64): int64 | Setzt die CPU-Affinität von pid auf die in cpuMask (alloc(CPU_SET_SIZE)) erlaubten CPUs. pid=0 → aktueller Prozess. Gibt 0 bei Erfolg |
SchedGetAffinity(pid: int64, outMask: int64): int64 | Liest die aktuelle CPU-Affinität von pid in outMask (alloc(CPU_SET_SIZE)). Gibt 0 bei Erfolg |
cpu_set_t-Helfer
| Signatur | Beschreibung |
|---|---|
CpuSetZero(buf: int64) | Setzt alle Bits auf 0 — keine CPU erlaubt |
CpuSetAdd(buf: int64, cpu: int64) | Erlaubt CPU cpu (0-basiert) in der Maske |
CpuSetRemove(buf: int64, cpu: int64) | Verbietet CPU cpu in der Maske |
CpuSetHas(buf: int64, cpu: int64): bool | Gibt true zurück wenn CPU cpu in der Maske gesetzt ist |
CpuSetCount(buf: int64): int64 | Zählt die Anzahl erlaubter CPUs in der Maske |
Prozess-Priorität (Nice-Wert)
| Signatur | Beschreibung |
|---|---|
GetPriority(pid: int64): int64 | Gibt den Nice-Wert von pid zurück (−20 = höchste, 19 = niedrigste Priorität). pid=0 → aktueller Prozess |
SetPriority(pid: int64, nice: int64): int64 | Setzt den Nice-Wert von pid. Nicht-Root kann nur erhöhen (Priorität senken). Gibt 0 bei Erfolg |
Aktuelle CPU
| Signatur | Beschreibung |
|---|---|
GetCPU(cpuOut: int64, nodeOut: int64): int64 | Schreibt CPU-Nummer in cpuOut und NUMA-Knoten in nodeOut (je alloc(8)). nodeOut=0 auf Nicht-NUMA-Systemen |
GetCurrentCPU(): int64 | Gibt die aktuelle CPU-Nummer direkt zurück (< 0 bei Fehler) |
Verwendung
Prozess auf eine CPU pinnen
import std.sched;
import std.alloc;
fn PinToCore(cpu: int64): bool {
var mask: int64 := alloc(CPU_SET_SIZE);
CpuSetZero(mask);
CpuSetAdd(mask, cpu);
var r := SchedSetAffinity(0, mask);
free(mask, CPU_SET_SIZE);
return r == 0;
}
Aktuelle Affinität lesen und ausgeben
import std.sched;
import std.alloc;
import std.io;
fn PrintAffinity(): void {
var mask: int64 := alloc(CPU_SET_SIZE);
SchedGetAffinity(0, mask);
Print("Erlaubte CPUs: ");
var cpu: int64 := 0;
while (cpu < 64) { // Erste 64 CPUs prüfen
if (CpuSetHas(mask, cpu)) {
Print(IntToStr(cpu) + " ");
}
cpu := cpu + 1;
}
PrintLn("Anzahl: " + IntToStr(CpuSetCount(mask)));
free(mask, CPU_SET_SIZE);
}
Prozess auf CPUs 0–3 beschränken
import std.sched;
import std.alloc;
fn LimitToFirstFourCores(): void {
var mask: int64 := alloc(CPU_SET_SIZE);
CpuSetZero(mask);
CpuSetAdd(mask, 0);
CpuSetAdd(mask, 1);
CpuSetAdd(mask, 2);
CpuSetAdd(mask, 3);
SchedSetAffinity(0, mask);
free(mask, CPU_SET_SIZE);
}
Nice-Wert und CPU-Diagnose
import std.sched;
import std.io;
fn PrintSchedInfo(): void {
var cpu := GetCurrentCPU();
var nice := GetPriority(0);
PrintLn("Läuft auf CPU: " + IntToStr(cpu));
PrintLn("Nice-Wert: " + IntToStr(nice));
}
fn LowerPriority(): void {
// Priorität senken (Nice erhöhen) — kein Root nötig
SetPriority(0, 10);
}
SchedYield in einer Spinloop
import std.sched;
// Gibt CPU ab während auf ein Flag gewartet wird (statt busy-wait).
fn WaitForFlag(flagAddr: int64): void {
while (peek64(flagAddr) == 0) {
SchedYield();
}
}
Hinweise
- CPU-Pinning erhöht die Cache-Lokalität bei rechenintensiven Prozessen, kann aber den Durchsatz bei I/O-lastigen Programmen senken.
SetPrioritymit einem Nice-Wert < 0 (höhere Priorität) erfordert Root oderCAP_SYS_NICE.GetCurrentCPUist nicht garantiert stabil: Der Scheduler kann den Prozess jederzeit auf eine andere CPU verschieben.SchedYieldgibt immer 0 zurück und schlägt nie fehl.CpuSetCountiteriert alle 128 Bytes (1024 CPUs) — für normale Systeme ist das vernachlässigbar.
Verwandte Units
std.process_ext— Credentials, Session, unamestd.thread— Threads (Affinität gilt pro Thread)std.process— fork, exec, waitpid
Letzte Aktualisierung: 2026-06-05
