Signatur
Beschreibung
pcntl_setcpuaffinity() ermöglicht es, einem Prozess bestimmte CPU-Kerne zuzuweisen. Das Betriebssystem schedulet den Prozess dann ausschließlich auf den angegebenen Kernen. Dies ist besonders nützlich in hochperformanten oder latenzempfindlichen Anwendungen, bei denen Cache-Lokalität und CPU-Isolation eine Rolle spielen.
Der Parameter $pid gibt die Prozess-ID des Zielprozesses an. Mit dem Wert 0 wird die Affinität des aktuellen Prozesses gesetzt. $cpus ist ein Array von Integer-Werten, das die Indizes der CPU-Kerne enthält (z. B. [0, 1] für Kern 0 und Kern 1).
Die Funktion ist nur auf Linux-Systemen verfügbar, auf denen die Erweiterung pcntl kompiliert wurde und das Betriebssystem sched_setaffinity() unterstützt. Auf anderen Plattformen (z. B. macOS, Windows) steht sie nicht zur Verfügung.
Typische Einsatzszenarien sind Multi-Process-Worker-Pools, bei denen einzelne Worker-Prozesse dediziert einem bestimmten CPU-Kern zugeordnet werden sollen, um NUMA-Effekte zu minimieren oder parallele Workloads sauber zu isolieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $pid Pflicht | int | Die Prozess-ID des Zielprozesses. Der Wert 0 steht für den aktuell laufenden Prozess. |
|
| $cpus Pflicht | array | Ein Array aus Integer-Werten, das die Indizes der CPU-Kerne enthält, auf denen der Prozess ausgeführt werden darf. Beispiel: [0, 2] erlaubt die Ausführung auf Kern 0 und Kern 2. |
Rückgabewert
true bei Erfolg zurück, false bei einem Fehler (z. B. unzureichende Berechtigungen, ungültige PID oder nicht unterstützte Plattform).Beispiele
CPU-Affinität des aktuellen Prozesses auf Kern 0 setzen
<?php
if (!function_exists('pcntl_setcpuaffinity')) {
die('pcntl_setcpuaffinity ist auf diesem System nicht verfügbar.');
}
// Aktuellen Prozess auf CPU-Kern 0 beschränken
$result = pcntl_setcpuaffinity(0, [0]);
if ($result) {
echo 'CPU-Affinität erfolgreich gesetzt.' . PHP_EOL;
// Zur Überprüfung aktuelle Affinität auslesen
$affinity = pcntl_getcpuaffinity(0);
echo 'Erlaubte Kerne: ' . implode(', ', $affinity) . PHP_EOL;
} else {
echo 'Fehler beim Setzen der CPU-Affinität.' . PHP_EOL;
}
Worker-Prozesse auf dedizierte CPU-Kerne verteilen
<?php
if (!function_exists('pcntl_fork') || !function_exists('pcntl_setcpuaffinity')) {
die('Benötigte pcntl-Funktionen nicht verfügbar.');
}
$numWorkers = 4;
$pids = [];
for ($i = 0; $i < $numWorkers; $i++) {
$pid = pcntl_fork();
if ($pid === -1) {
die('Fork fehlgeschlagen.');
} elseif ($pid === 0) {
// Kind-Prozess: auf dedizierten CPU-Kern setzen
$coreIndex = $i % $numWorkers;
if (pcntl_setcpuaffinity(0, [$coreIndex])) {
echo "Worker $i läuft auf Kern $coreIndex (PID: " . getmypid() . ")" . PHP_EOL;
} else {
echo "Worker $i: Affinität konnte nicht gesetzt werden." . PHP_EOL;
}
// Simulierte Arbeit
usleep(100000);
exit(0);
} else {
$pids[] = $pid;
}
}
// Elternprozess wartet auf alle Worker
foreach ($pids as $pid) {
pcntl_waitpid($pid, $status);
}
echo 'Alle Worker abgeschlossen.' . PHP_EOL;
// Wichtig · Fallstricke
Plattformverfügbarkeit: pcntl_setcpuaffinity() ist ausschließlich auf Linux verfügbar und setzt voraus, dass PHP mit der pcntl-Erweiterung kompiliert wurde. Auf macOS und Windows existiert diese Funktion nicht.
Berechtigungen: Um die CPU-Affinität eines fremden Prozesses (d. h. nicht des eigenen) zu setzen, sind in der Regel Root-Rechte oder entsprechende Capabilities (CAP_SYS_NICE) erforderlich. Für den eigenen Prozess ($pid = 0) reichen Nutzerrechte aus.
Ungültige Kern-Indizes: Wenn das $cpus-Array Kern-Indizes enthält, die auf dem System nicht vorhanden sind, schlägt der Aufruf fehl und gibt false zurück. Die maximale Anzahl von Kernen lässt sich z. B. über pcntl_getcpuaffinity() ermitteln.
Hinweis: Die Funktion steht erst ab PHP 8.1.0 zur Verfügung. Zur Gegenprüfung der gesetzten Affinität kann pcntl_getcpuaffinity() verwendet werden.