Start · Sprachen · PHP · Referenz · parallel\Channel

parallel\Channel

Klasse

Repräsentiert einen typsicheren Kommunikationskanal für den Austausch von Werten zwischen <code>parallel\Runtime</code>-Instanzen.

seit PHP 1.1.0 Kategorie: misc

Signatur

class parallel\Channel

Beschreibung

parallel\Channel ist Teil der parallel-Erweiterung und ermöglicht die strukturierte Kommunikation zwischen parallel laufenden Tasks. Kanäle können entweder gepuffert (mit einer festen Kapazität) oder ungepuffert sein. Bei ungepufferten Kanälen blockieren Sender und Empfänger gegenseitig, bis beide bereit sind – ähnlich wie Channels in Go oder Erlang.

Kanäle werden über parallel\Channel::make() erzeugt und können entweder anonym (lokal) oder benannt (global über parallel\Channel::open() zugänglich) sein. Benannte Kanäle erlauben es verschiedenen Laufzeitumgebungen, denselben Kanal anhand eines Namens zu teilen, ohne das Objekt selbst übergeben zu müssen.

Die Methoden send() und recv() sind die primären Operationen auf einem Kanal. send() legt einen Wert in den Kanal, recv() entnimmt ihn. Beide Methoden können blockieren, wenn der Kanal voll (bei gepufferten) bzw. noch leer (bei ungepufferten Kanälen) ist. Ein Kanal kann durch close() geschlossen werden, wodurch wartende recv()-Aufrufe mit einer Exception abbrechen.

Typische Einsatzgebiete sind Producer-Consumer-Muster, die Aggregation von Teil-Ergebnissen aus parallelen Tasks sowie die Synchronisation von Ausführungsschritten zwischen mehreren parallel\Runtime-Instanzen.

Parameter

Name Typ Default Beschreibung
$capacity int parallel\Channel::Infinite Kapazität des Kanalpuffers. 0 bedeutet ungepuffert (synchroner Kanal). Ein positiver Wert legt die maximale Anzahl gepufferter Nachrichten fest. parallel\Channel::Infinite erzeugt einen unbegrenzt gepufferten Kanal.

Rückgabewert

Typ

Beispiele

Einfacher ungepufferter Kanal zwischen zwei Tasks

<?php
use parallel\{Runtime, Channel};

$kanal = Channel::make(); // ungepuffert

$runtime = new Runtime();

$future = $runtime->run(function(Channel $ch) {
    // Empfange einen Wert vom Hauptthread
    $wert = $ch->recv();
    return $wert * 2;
}, [$kanal]);

// Sende einen Wert an den Task
$kanal->send(21);

echo $future->value(); // 42
42

Gepufferter benannter Kanal mit mehreren Tasks

<?php
use parallel\{Runtime, Channel};

// Benannten, gepufferten Kanal mit Kapazität 5 anlegen
$producer = Channel::make('ergebnisse', 5);

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

// Task 1: schreibt in den Kanal
$r1->run(function() {
    $ch = Channel::open('ergebnisse');
    foreach (range(1, 3) as $i) {
        $ch->send($i * 10);
    }
    $ch->close();
});

// Hauptthread liest aus dem Kanal
$ch = Channel::open('ergebnisse');
try {
    while (true) {
        echo $ch->recv() . PHP_EOL;
    }
} catch (\parallel\Channel\Error\Closed $e) {
    echo "Kanal geschlossen." . PHP_EOL;
}
10 20 30 Kanal geschlossen.

// Wichtig · Fallstricke

Achtung: parallel\Channel erfordert die PECL-Erweiterung parallel sowie PHP kompiliert mit ZTS (Zend Thread Safety). Im Standard-PHP ohne ZTS steht die Erweiterung nicht zur Verfügung.

Nicht alle PHP-Werte sind über Kanäle übertragbar. Objekte werden beim Senden serialisiert – Ressourcen (z. B. Datenbankverbindungen, Datei-Handles) können nicht übertragen werden und führen zu einer Exception.

Beim Versuch, auf einen bereits geschlossenen Kanal zu lesen oder zu schreiben, wird eine parallel\Channel\Error\Closed-Exception geworfen. Dieser Fall sollte stets abgefangen werden, um Deadlocks zu vermeiden.

Ungepufferte Kanäle (capacity = 0) können bei unsachgemäßem Einsatz zu Deadlocks führen, wenn Sender und Empfänger im selben Thread laufen oder die Reihenfolge von send/recv nicht aufeinander abgestimmt ist.