Start · Sprachen · PHP · Referenz · pcntl_sigprocmask

pcntl_sigprocmask

Funktion

Setzt oder ermittelt die Signalmaske des aktuellen Prozesses, um bestimmte Signale zu blockieren oder freizugeben.

seit PHP 5.3.0 Kategorie: misc

Signatur

pcntl_sigprocmask(int $how, array $signals, array &$old_signals = []): bool

Beschreibung

pcntl_sigprocmask() ermöglicht es, die Signalmaske eines Prozesses zu manipulieren. Die Signalmaske bestimmt, welche Signale vom Prozess blockiert werden sollen, d. h. vorläufig zurückgehalten und erst nach dem Entblockieren zugestellt werden. Dies ist besonders nützlich, wenn kritische Code-Abschnitte gegen Unterbrechungen durch Signale geschützt werden müssen.

Der Parameter how steuert, wie die Maske verändert wird: Mit SIG_BLOCK werden die angegebenen Signale zur bestehenden Maske hinzugefügt, mit SIG_UNBLOCK werden sie entfernt und mit SIG_SETMASK wird die Maske vollständig ersetzt. Die bisher aktive Signalmaske kann optional über den dritten Parameter $old_signals ausgelesen werden.

Die Funktion ist nur auf POSIX-kompatiblen Systemen (Linux, macOS, BSD) verfügbar und erfordert, dass PHP mit der PCNTL-Extension kompiliert wurde. Sie eignet sich typischerweise für Daemon-Prozesse, Worker-Skripte oder überall dort, wo Signalverarbeitung präzise gesteuert werden muss.

Hinweis: Blockierte Signale werden nicht verworfen, sondern in einer Warteschlange gehalten. Sobald das Signal entblockiert wird, wird es dem Prozess zugestellt.

Parameter

Name Typ Default Beschreibung
$how Pflicht int Steuert, wie die Signalmaske verändert wird. Mögliche Werte: SIG_BLOCK (Signale hinzufügen), SIG_UNBLOCK (Signale entfernen), SIG_SETMASK (Maske vollständig ersetzen).
$signals Pflicht array Ein Array von Signal-Konstanten (z. B. [SIGTERM, SIGINT]), die zur Signalmaske hinzugefügt, entfernt oder als neue Maske gesetzt werden sollen.
$old_signals array [] Wird als Referenz übergeben und enthält nach dem Aufruf die vorherige Signalmaske als Array von Signal-Konstanten. Nützlich, um die ursprüngliche Maske später wiederherstellen zu können.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. ungültiger Wert für how oder nicht unterstützte Plattform).

Beispiele

SIGTERM und SIGINT während eines kritischen Abschnitts blockieren

<?php
// SIGTERM und SIGINT blockieren, damit der kritische Abschnitt nicht unterbrochen wird
$blocked = [SIGTERM, SIGINT];
$oldMask = [];

if (pcntl_sigprocmask(SIG_BLOCK, $blocked, $oldMask)) {
    echo "Signale blockiert. Führe kritischen Code aus..." . PHP_EOL;

    // Simulierter kritischer Abschnitt
    sleep(2);
    echo "Kritischer Code abgeschlossen." . PHP_EOL;

    // Ursprüngliche Signalmaske wiederherstellen
    pcntl_sigprocmask(SIG_SETMASK, $oldMask);
    echo "Signalmaske wiederhergestellt." . PHP_EOL;
} else {
    echo "Fehler beim Setzen der Signalmaske." . PHP_EOL;
}
Signale blockiert. Führe kritischen Code aus... Kritischer Code abgeschlossen. Signalmaske wiederhergestellt.

Aktuelle Signalmaske auslesen ohne Änderung

<?php
// Aktuell blockierte Signale auslesen, ohne die Maske zu verändern
$currentMask = [];

// SIG_BLOCK mit leerem Array ändert die Maske nicht, befüllt aber $currentMask
pcntl_sigprocmask(SIG_BLOCK, [], $currentMask);

if (empty($currentMask)) {
    echo "Aktuell sind keine Signale blockiert." . PHP_EOL;
} else {
    echo "Aktuell blockierte Signale: " . implode(', ', $currentMask) . PHP_EOL;
}

// Einzelnes Signal zur Maske hinzufügen
pcntl_sigprocmask(SIG_BLOCK, [SIGUSR1]);
echo "SIGUSR1 wurde zur Signalmaske hinzugefügt." . PHP_EOL;

// SIGUSR1 wieder entfernen
pcntl_sigprocmask(SIG_UNBLOCK, [SIGUSR1]);
echo "SIGUSR1 wurde aus der Signalmaske entfernt." . PHP_EOL;
Aktuell sind keine Signale blockiert. SIGUSR1 wurde zur Signalmaske hinzugefügt. SIGUSR1 wurde aus der Signalmaske entfernt.

// Wichtig · Fallstricke

Plattformverfügbarkeit: pcntl_sigprocmask() ist nur auf POSIX-kompatiblen Systemen verfügbar (Linux, macOS, BSD). Unter Windows steht die Funktion nicht zur Verfügung.

Nicht blockierbare Signale: Die Signale SIGKILL und SIGSTOP können grundsätzlich nicht blockiert werden. Werden sie in $signals übergeben, werden sie vom Betriebssystem stillschweigend ignoriert.

Thread-Sicherheit: In Multi-Thread-Umgebungen (z. B. mit pthreads) wirkt sich die Signalmaske nur auf den aktuellen Thread aus. Für prozessweite Signalsteuerung sollte die Maske vor dem Erstellen von Threads gesetzt werden.

Zusammenspiel mit pcntl_sigwaitinfo(): Eine sinnvolle Kombination besteht darin, Signale zunächst zu blockieren und sie dann synchron per pcntl_sigwaitinfo() zu empfangen, um Race Conditions zu vermeiden.