Start · Sprachen · PHP · Referenz · pcntl_wait

pcntl_wait

Funktion

Wartet auf die Beendigung eines Kind-Prozesses und gibt dessen PID sowie Exit-Status zurück.

seit PHP 5.0.0 Kategorie: misc

Signatur

pcntl_wait(int &$status, int $flags = 0, array &$rusage = []): int

Beschreibung

pcntl_wait() blockiert den aufrufenden Prozess so lange, bis ein Kind-Prozess seinen Zustand ändert (typischerweise beendet). Sobald ein Kind beendet ist, wird dessen PID zurückgegeben und der Status in der per Referenz übergebenen Variable $status gespeichert. Diese Funktion entspricht dem POSIX-Systemaufruf wait(2) und ist unerlässlich, um so genannte Zombie-Prozesse zu vermeiden, die entstehen, wenn ein Elternprozess den Exitstatus eines beendeten Kind-Prozesses nicht einsammelt.

Der im Parameter $status gespeicherte Rohwert kann anschließend mit den Hilfsfunktionen pcntl_wifexited(), pcntl_wexitstatus(), pcntl_wifsignaled() und weiteren ausgewertet werden, um festzustellen, ob und wie das Kind beendet wurde.

Mit dem optionalen Parameter $flags lässt sich das Verhalten anpassen. Wird WNOHANG übergeben, kehrt die Funktion sofort zurück, wenn kein Kind seinen Zustand geändert hat (nicht-blockierender Modus). So kann der Elternprozess parallel weitere Arbeit erledigen und regelmäßig prüfen, ob Kinder fertig sind. Seit PHP 8.4 wird auch der Ressourcenverbrauch des Kindes über das dritte Argument $rusage bereitgestellt.

Diese Funktion steht nur unter Unix-ähnlichen Betriebssystemen zur Verfügung und setzt die PHP-Erweiterung pcntl voraus, die im CLI-Betrieb kompiliert sein muss.

Parameter

Name Typ Default Beschreibung
$status Pflicht int Wird per Referenz übergeben und enthält nach dem Aufruf den rohen Statuscode des beendeten Kind-Prozesses. Der Wert kann mit pcntl_wifexited(), pcntl_wexitstatus(), pcntl_wifsignaled() und verwandten Funktionen interpretiert werden.
$flags int 0 Optionale Bit-Flags. WNOHANG sorgt dafür, dass die Funktion sofort zurückkehrt, wenn kein Kind-Prozess seinen Zustand geändert hat. WUNTRACED meldet zusätzlich angehaltene Kinder, deren Status noch nicht berichtet wurde.
$rusage array [] Wird per Referenz übergeben und erhält nach dem Aufruf Ressourcenverbrauchs-Informationen des Kind-Prozesses (CPU-Zeit, Speichernutzung etc.), sofern das Betriebssystem diese Daten liefert.

Rückgabewert

Typ
int
Beschreibung
Gibt die PID des beendeten Kind-Prozesses zurück. Im nicht-blockierenden Modus (WNOHANG) wird 0 zurückgegeben, wenn kein Kind seinen Zustand geändert hat. Bei einem Fehler oder wenn keine Kinder vorhanden sind, wird -1 zurückgegeben.

Beispiele

Einfaches Warten auf einen Kind-Prozess

<?php
$pid = pcntl_fork();

if ($pid === -1) {
    die('Fork fehlgeschlagen');
} elseif ($pid === 0) {
    // Kind-Prozess
    echo "Kind (PID: " . getmypid() . ") arbeitet...\n";
    sleep(1);
    exit(42); // Exitcode 42
} else {
    // Eltern-Prozess wartet auf das Kind
    $childPid = pcntl_wait($status);

    if (pcntl_wifexited($status)) {
        $exitCode = pcntl_wexitstatus($status);
        echo "Kind (PID: $childPid) beendet mit Exitcode: $exitCode\n";
    }
}
Kind (PID: 12345) arbeitet... Kind (PID: 12345) beendet mit Exitcode: 42

Nicht-blockierendes Warten mit WNOHANG

<?php
$children = [];

// Mehrere Kind-Prozesse starten
for ($i = 0; $i < 3; $i++) {
    $pid = pcntl_fork();
    if ($pid === -1) {
        die('Fork fehlgeschlagen');
    } elseif ($pid === 0) {
        // Kind schläft unterschiedlich lang
        sleep(rand(1, 3));
        exit($i);
    } else {
        $children[$pid] = true;
    }
}

// Eltern prüft regelmäßig, ob Kinder fertig sind
while (!empty($children)) {
    $pid = pcntl_wait($status, WNOHANG);

    if ($pid > 0) {
        echo "Kind PID $pid beendet (Exit: " . pcntl_wexitstatus($status) . ")\n";
        unset($children[$pid]);
    } elseif ($pid === 0) {
        // Kein Kind fertig — Eltern kann andere Aufgaben erledigen
        echo "Warte auf Kinder...\n";
        sleep(1);
    } else {
        // Fehler oder keine Kinder mehr
        break;
    }
}

echo "Alle Kinder fertig.\n";
Warte auf Kinder... Warte auf Kinder... Kind PID 12346 beendet (Exit: 0) Kind PID 12347 beendet (Exit: 1) Kind PID 12348 beendet (Exit: 2) Alle Kinder fertig.

// Wichtig · Fallstricke

Zombie-Prozesse: Wird pcntl_wait() nicht aufgerufen, nachdem ein Kind-Prozess beendet wurde, verbleibt dieser als Zombie in der Prozesstabelle, bis der Elternprozess endet. Bei vielen lang laufenden Elternprozessen kann dies die Prozesstabelle des Systems erschöpfen.

Plattform: pcntl_wait() ist ausschließlich unter Unix/Linux verfügbar und steht unter Windows nicht zur Verfügung. Die pcntl-Erweiterung ist typischerweise nicht im Web-Server-Kontext (Apache-Modul, FPM) aktiv — sie sollte nur in CLI-Skripten verwendet werden.

Signal-Handling: Wenn der Elternprozess Signale empfängt, während er in pcntl_wait() blockiert, kann der Aufruf vorzeitig mit -1 und errno EINTR zurückkehren. In solchen Fällen empfiehlt sich eine Schleife mit erneutem Aufruf.