Start · Sprachen · PHP · Referenz · pcntl_setcpuaffinity

pcntl_setcpuaffinity

Funktion

Setzt die CPU-Affinität eines Prozesses, d. h. legt fest, auf welchen CPU-Kernen der Prozess ausgeführt werden darf.

seit PHP 8.1.0 Kategorie: misc

Signatur

pcntl_setcpuaffinity(int $pid, array $cpus): bool

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

Typ
bool
Beschreibung
Gibt 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;
}
CPU-Affinität erfolgreich gesetzt. Erlaubte Kerne: 0

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;
Worker 0 läuft auf Kern 0 (PID: 12345) Worker 1 läuft auf Kern 1 (PID: 12346) Worker 2 läuft auf Kern 2 (PID: 12347) Worker 3 läuft auf Kern 3 (PID: 12348) Alle Worker abgeschlossen.

// 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.