Signatur
Beschreibung
pcntl_sigtimedwait() blockiert die Ausführung des Prozesses, bis eines der in $signals angegebenen Signale eintrifft oder der angegebene Timeout (in Sekunden und Nanosekunden) abläuft. Die Funktion ist das zeitgesteuerte Gegenstück zu pcntl_sigwaitinfo() und erlaubt es, Signale synchron zu verarbeiten, ohne einen asynchronen Signal-Handler registrieren zu müssen.
Bevor Signale mit dieser Funktion abgewartet werden können, müssen sie typischerweise vorher mit pcntl_sigprocmask() blockiert werden (SIG_BLOCK), damit sie nicht von einem bestehenden Handler abgefangen werden, bevor pcntl_sigtimedwait() sie empfangen kann.
Im Erfolgsfall wird die Signalnummer zurückgegeben und das optionale Array $siginfo wird mit Informationen über das Signal befüllt (z. B. signo, errno, code, pid, uid usw.). Wenn der Timeout abläuft ohne dass ein Signal eintrifft, gibt die Funktion false zurück.
Die Funktion eignet sich besonders für Daemon-Prozesse oder Worker-Prozesse, die auf Kindprozess-Signale (SIGCHLD) oder Steuerungssignale wie SIGTERM, SIGHUP warten und gleichzeitig einen Timeout benötigen, um periodische Aufgaben auszuführen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $signals Pflicht | array | Array von Signalnummern (z. B. [SIGTERM, SIGCHLD]), auf die gewartet werden soll. |
|
| $siginfo | array | [] | Wird per Referenz übergeben und nach dem Empfang eines Signals mit Informationen befüllt. Enthält u. a. die Felder signo, errno, code, pid und uid. |
| $seconds | int | 0 | Timeout-Anteil in Sekunden. Werden sowohl seconds als auch nanoseconds auf 0 gesetzt, verhält sich die Funktion wie ein nicht-blockierender Poll. |
| $nanoseconds | int | 0 | Zusätzlicher Timeout-Anteil in Nanosekunden (0–999.999.999). Wird zu seconds addiert, um die Gesamtwartezeit zu bilden. |
Rückgabewert
int zurück, wenn eines der angegebenen Signale vor Ablauf des Timeouts eintrifft. Gibt false zurück, wenn der Timeout abgelaufen ist oder ein Fehler aufgetreten ist. Im Fehlerfall kann pcntl_get_last_error() zur Fehlerdiagnose genutzt werden.Beispiele
Auf SIGTERM oder SIGCHLD mit 5-Sekunden-Timeout warten
<?php
// Signale blockieren, damit sie nicht asynchron verarbeitet werden
pcntl_sigprocmask(SIG_BLOCK, [SIGTERM, SIGCHLD]);
echo "Warte auf Signal (max. 5 Sekunden)..." . PHP_EOL;
$siginfo = [];
$signo = pcntl_sigtimedwait([SIGTERM, SIGCHLD], $siginfo, 5, 0);
if ($signo === false) {
echo "Kein Signal empfangen — Timeout abgelaufen." . PHP_EOL;
} elseif ($signo === SIGTERM) {
echo "SIGTERM empfangen — Prozess wird beendet." . PHP_EOL;
echo "Gesendet von PID: " . $siginfo['pid'] . PHP_EOL;
exit(0);
} elseif ($signo === SIGCHLD) {
echo "SIGCHLD empfangen — Kindprozess beendet." . PHP_EOL;
pcntl_waitpid(-1, $status, WNOHANG);
}
Periodischer Daemon mit Signal-Überwachung
<?php
pcntl_sigprocmask(SIG_BLOCK, [SIGTERM, SIGHUP]);
$running = true;
while ($running) {
// Alle 2 Sekunden periodische Aufgabe ausführen
$siginfo = [];
$signo = pcntl_sigtimedwait([SIGTERM, SIGHUP], $siginfo, 2, 0);
if ($signo === SIGTERM) {
echo "SIGTERM empfangen. Daemon wird gestoppt." . PHP_EOL;
$running = false;
} elseif ($signo === SIGHUP) {
echo "SIGHUP empfangen. Konfiguration wird neu geladen." . PHP_EOL;
// reload_config();
} else {
// Timeout — periodische Arbeit erledigen
echo "Heartbeat: " . date('H:i:s') . PHP_EOL;
}
}
echo "Daemon beendet." . PHP_EOL;
// Wichtig · Fallstricke
Nur unter Unix/Linux verfügbar: pcntl_sigtimedwait() steht nur auf POSIX-kompatiblen Betriebssystemen zur Verfügung und ist unter Windows nicht nutzbar.
Signale vorher blockieren: Wenn die Signale nicht zuvor mit pcntl_sigprocmask(SIG_BLOCK, ...) blockiert wurden, können sie vom Standard-Handler abgefangen werden, bevor pcntl_sigtimedwait() sie erhält — das führt zu unerwartetem Verhalten.
Timeout von 0/0: Werden seconds und nanoseconds beide auf 0 gesetzt, führt die Funktion einen nicht-blockierenden Check durch und kehrt sofort zurück, falls kein Signal ansteht.
Diese Funktion ist nur verfügbar, wenn PHP mit der Option --enable-pcntl kompiliert wurde.