Signatur
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";
}
}
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;
}
}
// 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).