Signatur
Beschreibung
EvLoop ist Teil der Ev-Erweiterung und kapselt eine libev-Ereignisschleife. Während die Standard-Schleife (Singleton) über Ev::defaultLoop() bzw. EvLoop::defaultLoop() abgerufen wird, erlaubt EvLoop das Anlegen zusätzlicher, unabhängiger Schleifen – nützlich in Multithreading-Szenarien, wo jeder Thread seine eigene Schleife besitzen soll.
Watcher-Objekte (z. B. EvIo, EvTimer, EvSignal) werden einer konkreten EvLoop-Instanz zugeordnet. Über Methoden wie run(), stop(), now() und nowUpdate() kann der Lebenszyklus der Schleife vollständig gesteuert werden.
Die Klasse unterstützt verschiedene Backend-Flags (Ev::BACKEND_EPOLL, Ev::BACKEND_KQUEUE usw.), mit denen das zugrundeliegende I/O-Multiplexing-Verfahren gewählt wird. Wird kein Flag angegeben, wählt libev automatisch das beste verfügbare Backend.
Wichtig: Die Standard-Ereignisschleife ist nicht threadsicher. Für Child-Watcher (EvChild) darf ausschließlich die Standard-Schleife verwendet werden, da SIGCHLD nur einmal verarbeitet werden kann.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $flags | int | Ev::FLAG_AUTO | Kombination aus Ev::FLAG_*- und Ev::BACKEND_*-Konstanten, die das Verhalten und das I/O-Backend der Schleife festlegen. |
| $data | mixed | null | Beliebige benutzerdefinierte Daten, die der Schleife zugeordnet und über die data-Eigenschaft abgerufen werden können. |
| $io_interval | float | 0.0 | Mindestwartezeit (in Sekunden) zwischen zwei I/O-Abfragen. Ein höherer Wert reduziert die CPU-Last auf Kosten der Reaktionszeit. |
| $timeout_interval | float | 0.0 | Mindestwartezeit (in Sekunden) zwischen Timeout-Prüfungen. Erhöht die Effizienz bei vielen Timer-Watchern, verringert aber deren Genauigkeit. |
Beispiele
Eigene Ereignisschleife mit einem Timer-Watcher
<?php
// Eigene Schleife anlegen (kein Singleton)
$loop = new EvLoop(Ev::FLAG_AUTO);
// Timer: nach 1 Sekunde einmalig feuern
$timer = new EvTimer(1.0, 0.0, function () use ($loop) {
echo "Timer ausgelöst!" . PHP_EOL;
// Schleife nach dem Ereignis beenden
$loop->stop(Ev::BREAK_ALL);
}, null, $loop);
echo "Schleife startet..." . PHP_EOL;
$loop->run();
echo "Schleife beendet." . PHP_EOL;
Standard-Schleife abrufen und Backend ermitteln
<?php
// Standard-Schleife (Singleton) abrufen
$default = EvLoop::defaultLoop();
// Aktives Backend ausgeben
$backend = $default->backend();
$backendName = match ($backend) {
Ev::BACKEND_SELECT => 'select',
Ev::BACKEND_POLL => 'poll',
Ev::BACKEND_EPOLL => 'epoll',
Ev::BACKEND_KQUEUE => 'kqueue',
Ev::BACKEND_DEVPOLL => 'devpoll',
Ev::BACKEND_PORT => 'port',
default => 'unbekannt',
};
echo "Aktives Backend: " . $backendName . PHP_EOL;
echo "Aktuelle Zeit der Schleife: " . $default->now() . PHP_EOL;
// Wichtig · Fallstricke
Threadsicherheit: Jeder Thread sollte eine eigene EvLoop-Instanz verwenden. Die Standard-Schleife darf in Multithreading-Umgebungen nur im Haupt-Thread genutzt werden.
EvChild-Watcher können ausschließlich mit der Standard-Schleife (EvLoop::defaultLoop()) kombiniert werden, da das SIGCHLD-Signal global ist.
Die Ev-Erweiterung muss über PECL installiert werden (pecl install ev) und setzt eine mit libev kompilierte PHP-Umgebung voraus. Sie ist nicht im PHP-Kern enthalten.
Methoden wie verify() helfen beim Debuggen der internen Konsistenz der Schleife und sollten im Produktivbetrieb nicht aufgerufen werden, da sie die Performance beeinträchtigen.