Start · Sprachen · PHP · Referenz · pcntl_sigwaitinfo

pcntl_sigwaitinfo

Funktion

Blockiert den aufrufenden Prozess, bis eines der angegebenen Signale eintrifft, und liefert Informationen über das empfangene Signal zurück.

seit PHP 5.3.0 Kategorie: misc

Signatur

pcntl_sigwaitinfo(array $signals, array &$info = []): int|false

Beschreibung

pcntl_sigwaitinfo() suspendiert die Ausführung des aufrufenden Prozesses, bis ein Signal aus der übergebenen Menge $signals geliefert wird. Sobald ein solches Signal eintrifft, kehrt die Funktion zurück und gibt die Signalnummer zurück. Die Funktion ist nützlich, wenn ein Prozess synchron auf bestimmte Signale warten soll, anstatt asynchrone Signal-Handler (via pcntl_signal()) zu registrieren.

Über den optionalen Parameter $info (als Referenz übergeben) erhält man ein assoziatives Array mit detaillierten Informationen über das empfangene Signal, darunter Felder wie signo (Signalnummer), errno (Fehlercode), code (Signalursprungscode), pid (sendende Prozess-ID), uid (UID des sendenden Prozesses), status (Exit-Status oder Signalnummer bei Kindprozessen), utime, stime, addr und band.

Damit die Signale korrekt abgefangen werden können, müssen diese zuvor mit pcntl_sigprocmask() blockiert werden – andernfalls könnten sie vor dem Aufruf von pcntl_sigwaitinfo() bereits standardmäßig verarbeitet werden. Dieser Ansatz ist besonders in Daemon-Prozessen und bei der Implementierung von Kindprozess-Überwachung empfehlenswert.

Die Funktion steht nur auf POSIX-kompatiblen Systemen (Linux, macOS, BSD) zur Verfügung und ist unter Windows nicht verfügbar. Sie erfordert, dass PHP mit der PCNTL-Erweiterung kompiliert wurde.

Parameter

Name Typ Default Beschreibung
$signals Pflicht array Ein Array von Signalnummern (z. B. [SIGTERM, SIGCHLD]), auf die gewartet werden soll. Mindestens ein Signal muss angegeben werden.
$info array [] Wird als Referenz übergeben und nach dem Aufruf mit Informationen über das empfangene Signal befüllt. Enthält Felder wie signo, errno, code, pid, uid, status, utime, stime, addr und band.

Rückgabewert

Typ
int|false
Beschreibung
Gibt die Nummer des empfangenen Signals als int zurück. Im Fehlerfall (z. B. wenn ein ungültiges Signal angegeben wurde oder die Funktion durch ein nicht blockiertes Signal unterbrochen wurde) wird false zurückgegeben.

Beispiele

Synchrones Warten auf SIGTERM oder SIGCHLD

<?php
// Signale blockieren, damit sie nicht asynchron verarbeitet werden
pcntl_sigprocmask(SIG_BLOCK, [SIGTERM, SIGCHLD]);

echo "Warte auf SIGTERM oder SIGCHLD..." . PHP_EOL;

$info = [];
$signo = pcntl_sigwaitinfo([SIGTERM, SIGCHLD], $info);

if ($signo === false) {
    echo "Fehler beim Warten auf Signal." . PHP_EOL;
} else {
    echo "Signal empfangen: " . $signo . PHP_EOL;
    echo "Sendende PID: " . ($info['pid'] ?? 'n/a') . PHP_EOL;
    echo "Sendende UID: " . ($info['uid'] ?? 'n/a') . PHP_EOL;

    if ($signo === SIGTERM) {
        echo "SIGTERM empfangen – beende Prozess sauber." . PHP_EOL;
        exit(0);
    }
}
Warte auf SIGTERM oder SIGCHLD... Signal empfangen: 15 Sendende PID: 12345 Sendende UID: 1000 SIGTERM empfangen – beende Prozess sauber.

Kindprozess-Überwachung in einer Schleife

<?php
// Signale blockieren
pcntl_sigprocmask(SIG_BLOCK, [SIGCHLD, SIGTERM]);

$pid = pcntl_fork();

if ($pid === -1) {
    die('Fork fehlgeschlagen');
} elseif ($pid === 0) {
    // Kindprozess
    sleep(2);
    exit(42);
} else {
    // Elternprozess wartet auf Signale
    $running = true;
    while ($running) {
        $info = [];
        $signo = pcntl_sigwaitinfo([SIGCHLD, SIGTERM], $info);

        if ($signo === SIGCHLD) {
            $childPid = pcntl_waitpid(-1, $status, WNOHANG);
            if ($childPid > 0) {
                $exitCode = pcntl_wexitstatus($status);
                echo "Kindprozess {$childPid} beendet mit Exit-Code: {$exitCode}" . PHP_EOL;
            }
            $running = false;
        } elseif ($signo === SIGTERM) {
            echo "SIGTERM empfangen – beende." . PHP_EOL;
            $running = false;
        }
    }
}
Kindprozess 12346 beendet mit Exit-Code: 42

// Wichtig · Fallstricke

Wichtig: Signale, auf die mit pcntl_sigwaitinfo() gewartet werden soll, müssen vorher mit pcntl_sigprocmask(SIG_BLOCK, [...]) blockiert werden. Andernfalls kann das Signal schon vor dem Aufruf der Funktion standardmäßig verarbeitet worden sein, was zu unerwartetem Verhalten führt.

Die Funktion ist nicht unter Windows verfügbar – der Einsatz ist auf Unix-artige Systeme (Linux, macOS, BSD) beschränkt. Prüfe die Verfügbarkeit mit function_exists('pcntl_sigwaitinfo').

Wenn das Warten durch ein Signal unterbrochen wird, das nicht in $signals enthalten ist (und nicht blockiert wurde), gibt die Funktion false zurück und pcntl_errno() liefert EINTR. In einer Produktionsumgebung sollte man diesen Fall stets abfangen.

Für zeitlich begrenzte Warteoperationen bietet sich pcntl_sigtimedwait() an, das zusätzlich ein Timeout-Intervall akzeptiert.