Start · Sprachen · PHP · Referenz · proc_terminate

proc_terminate

Funktion

Sendet ein Signal an einen mit <code>proc_open()</code> gestarteten Prozess, um ihn zu beenden.

seit PHP 5.0.0 Kategorie: misc

Signatur

proc_terminate(resource $process, int $signal = 15): bool

Beschreibung

proc_terminate() sendet ein Signal an einen Prozess, der zuvor mit proc_open() gestartet wurde. Standardmäßig wird das Signal SIGTERM (Signal 15) gesendet, das den Prozess auffordert, sich sauber zu beenden. Alternativ kann ein anderes Signal angegeben werden, etwa SIGKILL (Signal 9) zum sofortigen Abbruch.

Die Funktion kehrt unmittelbar zurück, wartet also nicht darauf, dass der Prozess tatsächlich beendet wurde. Um sicherzustellen, dass der Prozess beendet ist und die zugehörigen Ressourcen freigegeben werden, sollte anschließend proc_close() oder proc_get_status() aufgerufen werden.

Auf Windows-Systemen wird das angegebene Signal ignoriert, und der Prozess wird unabhängig vom Signalwert stets mit der Windows-API beendet. Das Verhalten auf Unix-Systemen entspricht dem POSIX-Signal-Standard.

Typische Anwendungsfälle sind das Beenden von lang laufenden Hintergrundprozessen nach einem Timeout, das Abbrechen fehlgeschlagener oder hängender Subprozesse sowie das saubere Aufräumen von Prozessressourcen in Fehlerszenarien.

Parameter

Name Typ Default Beschreibung
$process Pflicht resource Die Prozess-Ressource, die von proc_open() zurückgegeben wurde.
$signal int 15 Das zu sendende POSIX-Signal (z. B. SIGTERM = 15, SIGKILL = 9). Auf Windows-Systemen wird dieser Parameter ignoriert.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn das Signal erfolgreich gesendet wurde (nicht, ob der Prozess beendet wurde), oder false bei einem Fehler, z. B. wenn die übergebene Ressource ungültig ist.

Beispiele

Prozess mit SIGTERM beenden

<?php
$descriptorspec = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe', 'w'],
];

$process = proc_open('sleep 60', $descriptorspec, $pipes);

if (is_resource($process)) {
    echo "Prozess gestartet.\n";

    // Prozess mit SIGTERM (15) beenden
    $result = proc_terminate($process);

    echo $result ? "Terminierungssignal gesendet.\n" : "Fehler beim Senden des Signals.\n";

    // Prozess schließen und Exit-Code ermitteln
    $exitCode = proc_close($process);
    echo "Exit-Code: $exitCode\n";
}
Prozess gestartet. Terminierungssignal gesendet. Exit-Code: 143

Prozess mit Timeout und SIGKILL erzwingen

<?php
$descriptorspec = [
    0 => ['pipe', 'r'],
    1 => ['pipe', 'w'],
    2 => ['pipe', 'w'],
];

$process = proc_open('php -r "sleep(120);"', $descriptorspec, $pipes);

if (is_resource($process)) {
    $timeout = 3; // Sekunden
    $start = time();

    while (true) {
        $status = proc_get_status($process);

        if (!$status['running']) {
            echo "Prozess hat sich selbst beendet.\n";
            break;
        }

        if ((time() - $start) >= $timeout) {
            echo "Timeout erreicht – erzwinge Beendigung mit SIGKILL.\n";
            proc_terminate($process, 9); // SIGKILL
            break;
        }

        usleep(200000); // 200 ms warten
    }

    proc_close($process);
}
Timeout erreicht – erzwinge Beendigung mit SIGKILL.

// Wichtig · Fallstricke

Wichtig: proc_terminate() wartet nicht auf das tatsächliche Beenden des Prozesses. Wird nach dem Aufruf sofort proc_close() aufgerufen, kann es zu einem kurzen Blockieren kommen, bis der Prozess tatsächlich beendet ist.

Alle zu dem Prozess gehörenden Pipes sollten vor dem Aufruf von proc_close() mit fclose() geschlossen werden, um Deadlocks durch vollgeschriebene Pipe-Puffer zu vermeiden.

Auf Windows-Systemen wird der Prozess immer sofort beendet, unabhängig vom angegebenen Signalwert. Das Verhalten entspricht daher immer einem erzwungenen Abbruch (analog zu SIGKILL).

Bei der Arbeit mit Benutzereingaben als Prozessargumente sollten diese stets mit escapeshellarg() oder escapeshellcmd() abgesichert werden, um Command-Injection zu verhindern.