Signatur
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
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";
}
}
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";
// 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.