Start · Sprachen · PHP · Referenz · parallel\Future

parallel\Future

Klasse

Repräsentiert das zukünftige Ergebnis einer asynchron in einem <code>parallel\Runtime</code>-Thread ausgeführten Aufgabe.

seit PHP 1.0.0 Kategorie: misc

Signatur

class parallel\Future

Beschreibung

parallel\Future ist ein Platzhalter-Objekt, das beim Aufruf von parallel\Runtime::run() zurückgegeben wird. Es kapselt das Ergebnis einer Closure, die in einem separaten PHP-Thread läuft. Der aufrufende Thread kann das Ergebnis zu einem beliebigen späteren Zeitpunkt abrufen, ohne den Ablauf sofort blockieren zu müssen.

Mit der Methode value() wartet der aktuelle Thread so lange, bis die asynchrone Aufgabe abgeschlossen ist, und gibt dann den Rückgabewert der Closure zurück. Wirft die Closure eine Exception, wird diese beim Aufruf von value() erneut geworfen, sodass Fehler transparent weitergeleitet werden.

Über cancelled() und done() lässt sich der Zustand des Futures abfragen, ohne blockieren zu müssen. Mit cancel() kann eine noch nicht gestartete oder wartende Aufgabe abgebrochen werden. Dies ermöglicht ein nicht-blockierendes Polling-Muster, bei dem mehrere Futures parallel überwacht werden.

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

Beispiele

Einfaches Future: Ergebnis einer asynchronen Berechnung abrufen

<?php
use parallel\Runtime;

$runtime = new Runtime();

// Startet eine Closure in einem separaten Thread
$future = $runtime->run(function (): int {
    // Simuliert eine aufwändige Berechnung
    $sum = 0;
    for ($i = 1; $i <= 1_000_000; $i++) {
        $sum += $i;
    }
    return $sum;
});

// Anderer Code kann hier ausgeführt werden ...
echo "Berechnung läuft im Hintergrund ...\n";

// Wartet auf das Ergebnis und gibt es aus
$result = $future->value();
echo "Ergebnis: " . $result . PHP_EOL;
Berechnung läuft im Hintergrund ... Ergebnis: 500000500000

Fehlerbehandlung: Exception aus dem Thread abfangen

<?php
use parallel\Runtime;

$runtime = new Runtime();

$future = $runtime->run(function (): void {
    throw new RuntimeException('Fehler im asynchronen Thread!');
});

try {
    $future->value();
} catch (\Throwable $e) {
    echo 'Exception gefangen: ' . $e->getMessage() . PHP_EOL;
}
Exception gefangen: Fehler im asynchronen Thread!

Status-Polling: done() und cancel() verwenden

<?php
use parallel\Runtime;

$runtime = new Runtime();

$future = $runtime->run(function (): string {
    sleep(2);
    return 'fertig';
});

// Nicht-blockierendes Polling
if (!$future->done()) {
    echo "Aufgabe läuft noch ...\n";
}

// Optional: Aufgabe abbrechen (nur möglich, solange sie noch nicht läuft)
if (!$future->done() && !$future->cancelled()) {
    // $future->cancel(); // würde die Aufgabe abbrechen
}

// Blockierendes Warten auf das Ergebnis
$value = $future->value();
echo 'Ergebnis: ' . $value . PHP_EOL;
Aufgabe läuft noch ... Ergebnis: fertig

// Wichtig · Fallstricke

ZTS erforderlich: Die parallel-Erweiterung funktioniert ausschließlich mit einem thread-sicheren PHP-Build (ZTS). Standard-PHP-Binaries unter vielen Linux-Distributionen sind nicht ZTS-fähig. Prüfe mit php -r "echo ZEND_THREAD_SAFE ? 'ZTS' : 'NTS';".

Datenaustausch: Nur serialisierbare Werte können zwischen Threads ausgetauscht werden. Ressourcen, Closures (außer als Aufgabe selbst) und bestimmte interne Objekte können nicht übergeben werden. Nicht-serialisierbare Rückgabewerte führen zu einem Laufzeitfehler.

cancel()-Einschränkungen: Eine bereits laufende Aufgabe kann nicht abgebrochen werden — cancel() ist nur effektiv, wenn die Aufgabe noch in der Warteschlange ist. Der Rückgabewert von cancel() zeigt an, ob der Abbruch erfolgreich war.

Ressourcen freigeben: Nach Abschluss aller Futures sollte Runtime::close() oder Runtime::kill() aufgerufen werden, um den Thread ordnungsgemäß zu beenden und Ressourcen freizugeben.