Start · Sprachen · PHP · Referenz · parallel\Runtime

parallel\Runtime

Klasse

Repräsentiert eine isolierte PHP-Laufzeitumgebung (Thread), in der Aufgaben parallel ausgeführt werden können.

seit PHP 1.0.0 Kategorie: misc

Signatur

class parallel\Runtime

Beschreibung

parallel\Runtime ist das zentrale Objekt der parallel-Erweiterung und kapselt einen einzelnen POSIX-Thread mit eigenem PHP-Interpreter-Zustand. Jede Instanz startet einen neuen, vollständig isolierten Ausführungskontext, der unabhängig vom Haupt-Thread läuft. Über die Methode run() werden \Closure-Objekte in diesem Thread ausgeführt und liefern optionale parallel\Future-Objekte zurück, mit denen das Ergebnis abgerufen werden kann.

Da jeder Runtime-Thread einen eigenen Zustand besitzt, können keine gemeinsamen PHP-Objekte oder Ressourcen direkt übergeben werden. Nur bestimmte, serialisierbare Werte (Zahlen, Strings, Arrays, parallel\Channel-Objekte) dürfen als Argumente an Tasks übergeben werden. Klassen mit __clone-Verboten, Closures über nicht-serialisierbare Bindungen oder Ressourcen wie Datenbankverbindungen sind explizit ausgeschlossen.

Der Konstruktor akzeptiert optional den Pfad zu einem Bootstrap-Skript (typischerweise der Composer-Autoloader), das vor dem ersten run()-Aufruf im Thread ausgeführt wird und so sicherstellt, dass alle benötigten Klassen im Kontext des Threads verfügbar sind.

Wenn eine Runtime-Instanz nicht mehr benötigt wird, sollte close() aufgerufen werden, um den Thread geordnet zu beenden, oder kill(), um ihn sofort abzubrechen. Das Zerstören einer Runtime ohne explizites Schließen blockiert, bis alle laufenden Tasks abgeschlossen sind.

Parameter

Name Typ Default Beschreibung
$bootstrap string Optionaler Pfad zu einem PHP-Skript (z. B. vendor/autoload.php), das im neuen Thread als erstes ausgeführt wird, um den Autoloader oder andere globale Initialisierungen bereitzustellen.

Beispiele

Einfache parallele Berechnung mit Future

<?php
require 'vendor/autoload.php';

use parallel\Runtime;

$runtime = new Runtime();

$future = $runtime->run(function (int $n): int {
    // Läuft in einem separaten Thread
    $sum = 0;
    for ($i = 1; $i <= $n; $i++) {
        $sum += $i;
    }
    return $sum;
}, [1000]);

// Hauptthread kann hier andere Arbeit erledigen
echo 'Warte auf Ergebnis...' . PHP_EOL;

// Ergebnis abrufen (blockiert bis Task fertig ist)
$result = $future->value();
echo 'Summe 1 bis 1000: ' . $result . PHP_EOL;

$runtime->close();
Warte auf Ergebnis... Summe 1 bis 1000: 500500

Mehrere Runtimes mit Bootstrap-Skript

<?php
use parallel\Runtime;
use parallel\Future;

$bootstrap = __DIR__ . '/vendor/autoload.php';

// Drei Runtimes für parallele HTTP-Verarbeitung o. ä.
$runtimes = array_map(
    fn() => new Runtime($bootstrap),
    range(1, 3)
);

$tasks = [10, 20, 30];

/** @var Future[] $futures */
$futures = [];
foreach ($runtimes as $index => $runtime) {
    $futures[$index] = $runtime->run(
        function (int $value): string {
            // Klasse aus Autoloader nutzbar dank Bootstrap
            return 'Ergebnis für ' . $value . ': ' . ($value * $value);
        },
        [$tasks[$index]]
    );
}

foreach ($futures as $index => $future) {
    echo $future->value() . PHP_EOL;
}

foreach ($runtimes as $runtime) {
    $runtime->close();
}
Ergebnis für 10: 100 Ergebnis für 20: 400 Ergebnis für 30: 900

// Wichtig · Fallstricke

Einschränkungen bei Closures: Die an run() übergebene \Closure darf keine Referenzen auf Objekte aus dem Haupt-Thread binden (kein use ($objekt) mit nicht-serialisierbaren Objekten). Erlaubt sind primitive Typen, Arrays und parallel\Channel-Objekte.

Kein gemeinsamer Zustand: Jede Runtime ist vollständig isoliert. Globale Variablen, statische Klasseneigenschaften oder Singletons werden nicht zwischen Threads geteilt. Kommunikation sollte über parallel\Channel erfolgen.

PHP-Voraussetzung: Die parallel-Erweiterung erfordert PHP mit ZTS (Zend Thread Safety), das heißt PHP muss mit --enable-zts kompiliert sein. Standardmäßige PHP-Binaries sind oft nicht ZTS-fähig.

Ressourcen-Leaks: Nicht geschlossene Runtimes blockieren beim Destruktor. Immer close() im Normalfall und kill() im Fehlerfall aufrufen, um Threads sauber zu beenden.