Start · Sprachen · PHP · Referenz · EvChild

EvChild

Klasse

Überwacht die Beendigung oder Statusänderung eines Kindprozesses mittels der <code>libev</code>-Ereignisschleife.

Kategorie: io

Signatur

class EvChild extends EvWatcher

Beschreibung

EvChild ist ein Watcher aus der ev-PECL-Erweiterung und reagiert auf Statusänderungen von Kindprozessen – insbesondere auf deren Beendigung. Intern nutzt er den POSIX-Mechanismus SIGCHLD, um effizient auf Prozess-Events zu warten, ohne aktiv pollen zu müssen.

Typische Einsatzgebiete sind asynchrone Prozessverwaltung: Ein übergeordneter Prozess startet mit pcntl_fork() einen oder mehrere Kindprozesse und verwendet EvChild, um zu erfahren, wann diese enden und mit welchem Exit-Code. So lassen sich Ressourcen korrekt freigeben und nachfolgende Schritte einleiten.

Der Watcher wird immer im Standard-Event-Loop (EvLoop::defaultLoop()) ausgeführt, da SIGCHLD-Signalverarbeitung nur dort zuverlässig funktioniert. Ein EvChild-Watcher im Kontext eines anderen Loops ist nicht sinnvoll.

Innerhalb des Callbacks stehen über das $watcher-Objekt wichtige Eigenschaften zur Verfügung: $watcher->rpid enthält die tatsächliche PID des beendeten Kindprozesses und $watcher->rstatus den Raw-Exit-Status, der mit den pcntl_*-Funktionen (z. B. pcntl_wexitstatus()) ausgewertet werden kann.

Parameter

Name Typ Default Beschreibung
$pid Pflicht int PID des zu überwachenden Kindprozesses. Der Wert 0 überwacht alle Kindprozesse des aktuellen Prozesses.
$trace Pflicht bool Wenn true, wird der Watcher auch bei gestoppten (nicht nur bei beendeten) Kindprozessen ausgelöst (entspricht WUNTRACED in POSIX). Normalerweise false.
$callback Pflicht callable Callback-Funktion, die aufgerufen wird, wenn der Kindprozess seinen Status ändert. Signatur: function(EvChild $watcher, int $revents): void.
$data mixed null Beliebige benutzerdefinierte Daten, die dem Watcher beigefügt und im Callback über $watcher->data abgerufen werden können.
$priority int 0 Priorität des Watchers. Höhere Werte bedeuten höhere Priorität. Gültige Werte liegen im Bereich Ev::MINPRI bis Ev::MAXPRI.

Rückgabewert

Typ
void

Beispiele

Kindprozess starten und Beendigung überwachen

<?php
// Nur im Default-Loop möglich!
$pid = pcntl_fork();

if ($pid === 0) {
    // Kindprozess: simuliert Arbeit und beendet sich
    sleep(1);
    exit(42);
}

if ($pid > 0) {
    // Elternprozess: EvChild-Watcher anlegen
    $watcher = new EvChild(
        $pid,
        false,
        function (EvChild $w, int $revents) {
            echo "Kindprozess PID {$w->rpid} beendet." . PHP_EOL;
            $exitCode = pcntl_wexitstatus($w->rstatus);
            echo "Exit-Code: {$exitCode}" . PHP_EOL;
            $w->stop(); // Watcher stoppen
            Ev::stop();  // Event-Loop beenden
        }
    );

    Ev::run(); // Event-Loop starten
}
Kindprozess PID 12345 beendet. Exit-Code: 42

Alle Kindprozesse überwachen (pid = 0)

<?php
$pids = [];

// Mehrere Kindprozesse starten
for ($i = 0; $i < 3; $i++) {
    $pid = pcntl_fork();
    if ($pid === 0) {
        sleep(rand(1, 3));
        exit($i + 1);
    }
    $pids[] = $pid;
}

$finished = 0;
$total    = count($pids);

// pid=0 => alle Kindprozesse überwachen
$watcher = new EvChild(
    0,
    false,
    function (EvChild $w, int $revents) use (&$finished, $total) {
        $exit = pcntl_wexitstatus($w->rstatus);
        echo "Kind-PID {$w->rpid} beendet mit Exit-Code {$exit}" . PHP_EOL;
        $finished++;
        if ($finished >= $total) {
            $w->stop();
            Ev::stop();
        }
    }
);

Ev::run();
Kind-PID 12346 beendet mit Exit-Code 1 Kind-PID 12347 beendet mit Exit-Code 2 Kind-PID 12348 beendet mit Exit-Code 3

// Wichtig · Fallstricke

Achtung: EvChild-Watcher dürfen ausschließlich im Standard-Event-Loop (EvLoop::defaultLoop() bzw. über die statische Ev::run()-API) verwendet werden. In benutzerdefinierten Loops ist das Verhalten undefiniert, da die SIGCHLD-Verarbeitung global ist.

Der rstatus-Wert ist der rohe POSIX-Wait-Status. Für eine sinnvolle Auswertung sollten pcntl_wifexited(), pcntl_wexitstatus(), pcntl_wifsignaled() und pcntl_wtermsig() verwendet werden.

Die ev-Erweiterung muss über PECL installiert sein (pecl install ev). Sie steht nicht standardmäßig in PHP zur Verfügung.