Start · Sprachen · PHP · Referenz · pcntl_sigtimedwait

pcntl_sigtimedwait

Funktion

Wartet mit einem konfigurierbaren Timeout auf eines der angegebenen Signale und gibt Informationen über das empfangene Signal zurück.

seit PHP 5.3.0 Kategorie: misc

Signatur

pcntl_sigtimedwait(array $signals, array &$siginfo = [], int $seconds = 0, int $nanoseconds = 0): int|false

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

Typ
int|false
Beschreibung
Gibt die Nummer des empfangenen Signals als 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);
}
Warte auf Signal (max. 5 Sekunden)... Kein Signal empfangen — Timeout abgelaufen.

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;
Heartbeat: 12:00:02 Heartbeat: 12:00:04 SIGTERM empfangen. Daemon wird gestoppt. Daemon beendet.

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