Start · Sprachen · PHP · Referenz · parallel\Events

parallel\Events

Klasse

Verwaltet und liefert Ereignisse von <code>Channel</code>s und <code>Future</code>s aus der parallel-Extension.

seit PHP 1.1.0 Kategorie: misc

Signatur

class parallel\Events implements Countable

Beschreibung

parallel\Events ist ein Ereignis-Loop für die parallele Ausführung in PHP. Mit dieser Klasse lassen sich mehrere Channel- und Future-Objekte gleichzeitig überwachen, ohne für jedes einzeln blockierend warten zu müssen. Das ist das zentrale Werkzeug, wenn mehrere parallele Aufgaben koordiniert werden sollen.

Typische Anwendungsfälle sind: Warten auf das zuerst verfügbare Ergebnis aus mehreren parallel laufenden Runtime-Aufgaben, nicht-blockierendes Lesen aus mehreren Channels sowie das geordnete Verarbeiten eingehender Ereignisse aus einem verteilten Task-Pool.

Die Klasse arbeitet nach dem Prinzip einer Ereignisschleife: Man fügt Targets (Channels oder Futures) hinzu, setzt optional einen Timeout und ruft dann wiederholt poll() auf, das jeweils das nächste verfügbare Ereignis als parallel\Events\Event-Objekt zurückliefert oder null, wenn keine Ereignisse mehr vorhanden sind.

Ein wichtiges Detail: Wird ein Eingabe-Wert für einen Channel benötigt (Schreib-Ereignis), muss dieser über setInput() gesetzt werden, bevor poll() aufgerufen wird. Jedes Target wird nach dem ersten ausgelösten Ereignis automatisch aus der Events-Instanz entfernt, sofern es sich um ein Future handelt; Channels bleiben aktiv.

Beispiele

Mehrere Futures gleichzeitig überwachen

<?php
use parallel\Runtime;
use parallel\Events;
use parallel\Events\Event\Type;

$r1 = new Runtime();
$r2 = new Runtime();

$f1 = $r1->run(function () {
    usleep(200000);
    return 'Ergebnis A';
});

$f2 = $r2->run(function () {
    usleep(100000);
    return 'Ergebnis B';
});

$events = new Events();
$events->addFuture('future1', $f1);
$events->addFuture('future2', $f2);
$events->setBlocking(true);

while ($event = $events->poll()) {
    if ($event->type === Type::Read) {
        echo "Ereignis von {$event->source}: {$event->value}\n";
    }
}
Ereignis von future2: Ergebnis B Ereignis von future1: Ergebnis A

Channel-Ereignisse mit Timeout und setInput

<?php
use parallel\Runtime;
use parallel\Channel;
use parallel\Events;
use parallel\Events\Event\Type;

$channel = Channel::make('mein-kanal');

$runtime = new Runtime();
$runtime->run(function () {
    $ch = Channel::open('mein-kanal');
    $ch->send('Hallo aus der Task!');
    $ch->close();
});

$events = new Events();
$events->addChannel($channel);
$events->setTimeout(2000000); // 2 Sekunden in Mikrosekunden
$events->setBlocking(true);

while ($event = $events->poll()) {
    if ($event->type === Type::Read) {
        echo "Empfangen: {$event->value}\n";
    } elseif ($event->type === Type::Close) {
        echo "Kanal wurde geschlossen.\n";
        break;
    }
}
Empfangen: Hallo aus der Task! Kanal wurde geschlossen.

// Wichtig · Fallstricke

Blocking-Modus: Standardmäßig arbeitet parallel\Events nicht-blockierend. Mit setBlocking(true) blockiert poll() so lange, bis ein Ereignis verfügbar ist. Im nicht-blockierenden Modus gibt poll() sofort null zurück, wenn kein Ereignis vorliegt — Busy-Waiting ist dann Aufgabe des Entwicklers.

Timeout: Mit setTimeout() wird ein Timeout in Mikrosekunden gesetzt. Bei Überschreitung wird eine parallel\Events\Error\Timeout-Exception geworfen, keine stille null-Rückgabe.

Schreib-Ereignisse: Soll über die Events-Instanz in einen Channel geschrieben werden, muss der Wert vorher via setInput() hinterlegt werden, da poll() sonst eine Exception wirft.

Voraussetzung: Die parallel-Extension erfordert PHP 8.0+ mit ZTS (Zend Thread Safety) und muss separat installiert werden (pecl install parallel).