Start · Sprachen · PHP · Referenz · pcntl_signal_dispatch

pcntl_signal_dispatch

Funktion

Ruft alle registrierten Signal-Handler für ausstehende Signale auf und verarbeitet diese synchron.

seit PHP 5.3.0 Kategorie: misc

Signatur

pcntl_signal_dispatch(): bool

Beschreibung

pcntl_signal_dispatch() verarbeitet alle im aktuellen Prozess ausstehenden Signale, indem die dafür registrierten Callback-Funktionen (Handler) aufgerufen werden. Die Funktion ist besonders dann nützlich, wenn declare(ticks=1) nicht verwendet wird und man die Signal-Verarbeitung manuell steuern möchte – etwa in langen Schleifen oder nach intensiven Berechnungen.

In modernen PHP-Anwendungen (ab 5.3.0) ist es empfohlen, anstelle von declare(ticks=1) explizit pcntl_signal_dispatch() an geeigneten Stellen im Code aufzurufen. Dies gibt dem Entwickler volle Kontrolle darüber, wann Signale verarbeitet werden, und vermeidet den Performance-Overhead, den das automatische Tick-System verursacht.

Typische Einsatzszenarien sind Daemon-Prozesse, Worker-Skripte oder lang laufende CLI-Anwendungen, die auf Signale wie SIGTERM, SIGHUP oder SIGUSR1 reagieren müssen. Der Aufruf sollte in regelmäßigen Abständen – z. B. am Anfang oder Ende jeder Schleifen-Iteration – erfolgen.

Die Funktion setzt voraus, dass Signale zuvor mit pcntl_signal() registriert wurden. Ohne vorherige Registrierung hat pcntl_signal_dispatch() keinen Effekt, da keine Handler vorhanden sind, die ausgeführt werden könnten.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Dispatch-Operation erfolgreich war. Gibt false zurück, wenn ein Fehler aufgetreten ist (z. B. wenn die PCNTL-Erweiterung nicht verfügbar ist).

Beispiele

Signal-Handler in einer Worker-Schleife ohne ticks

<?php
// Signal-Handler registrieren
$running = true;

pcntl_signal(SIGTERM, function (int $signal) use (&$running): void {
    echo "SIGTERM empfangen – beende Worker...\n";
    $running = false;
});

pcntl_signal(SIGHUP, function (int $signal): void {
    echo "SIGHUP empfangen – Konfiguration neu laden...\n";
    // Konfiguration hier neu einlesen
});

echo "Worker gestartet (PID: " . getmypid() . ")\n";

while ($running) {
    // Eigentliche Arbeit des Workers
    // ...

    // Ausstehende Signale explizit verarbeiten
    pcntl_signal_dispatch();

    sleep(1);
}

echo "Worker wurde sauber beendet.\n";
Worker gestartet (PID: 12345) SIGTERM empfangen – beende Worker... Worker wurde sauber beendet.

Vergleich: Manueller Dispatch vs. declare(ticks=1)

<?php
// Alte Methode mit ticks (Performance-Overhead bei jeder Anweisung)
// declare(ticks=1);

// Moderne Methode: expliziter Dispatch
pcntl_signal(SIGUSR1, function (int $signal): void {
    echo "SIGUSR1 empfangen um: " . date('H:i:s') . "\n";
});

$iterations = 0;

while ($iterations < 5) {
    // Simulierte Aufgabe
    usleep(500000); // 0,5 Sekunden warten
    $iterations++;

    // Signale manuell dispatchen – ohne Overhead durch ticks
    pcntl_signal_dispatch();

    echo "Iteration $iterations abgeschlossen.\n";
}

echo "Fertig.\n";
Iteration 1 abgeschlossen. Iteration 2 abgeschlossen. Iteration 3 abgeschlossen. Iteration 4 abgeschlossen. Iteration 5 abgeschlossen. Fertig.

// Wichtig · Fallstricke

Plattformverfügbarkeit: pcntl_signal_dispatch() steht nur auf Unix-ähnlichen Betriebssystemen zur Verfügung. Unter Windows ist die PCNTL-Erweiterung nicht verfügbar.

Kein automatisches Dispatching: Ohne declare(ticks=1) oder explizite Aufrufe von pcntl_signal_dispatch() werden ausstehende Signale nicht automatisch verarbeitet. In lang laufenden Prozessen ohne Dispatch-Aufrufe kann es zu einem Aufstauen von Signalen kommen, die dann erst beim nächsten Dispatch-Aufruf gebündelt abgearbeitet werden.

Reentranz: Signal-Handler sollten möglichst kurz und einfach gehalten werden, da PHP nicht reentrant-sicher ist. Komplexe Operationen (z. B. Datenbankzugriffe) innerhalb von Signal-Handlern können zu unerwartetem Verhalten führen. Besser ist es, im Handler nur ein Flag zu setzen und die eigentliche Logik im normalen Programmfluss auszuführen.

Async-Signals: Ab PHP 7.1 kann pcntl_async_signals(true) aktiviert werden, um Signale ohne declare(ticks=1) asynchron zu verarbeiten. In diesem Fall ist pcntl_signal_dispatch() nicht mehr notwendig.