Signatur
Beschreibung
Swoole\Channel implementiert einen blockierenden FIFO-Puffer im gemeinsam genutzten Speicher (Shared Memory), über den mehrere Prozesse Nachrichten austauschen können. Er eignet sich besonders für Szenarien, in denen Swoole\Process-Kinder-Prozesse Daten an einen Master-Prozess senden oder umgekehrt, ohne auf Sockets oder Pipes angewiesen zu sein.
Der Kanal funktioniert nach dem Producer-Consumer-Prinzip: Ein Prozess schreibt Daten mit push() in den Puffer, ein anderer liest sie mit pop() heraus. Da der Kanal auf Shared Memory basiert, ist er deutlich schneller als Pipe- oder Socket-basierte IPC-Mechanismen, hat jedoch eine feste maximale Kapazität, die beim Erstellen festgelegt wird.
Ein wichtiger Unterschied zu Swoole\Table ist, dass Swoole\Channel als Warteschlange (Queue) konzipiert ist: Daten werden sequentiell gelesen und dabei aus dem Puffer entfernt. Komplexe PHP-Strukturen wie Arrays und Objekte werden dabei automatisch serialisiert.
Der Kanal muss vor dem Erstellen der Kind-Prozesse instanziiert werden, damit alle beteiligten Prozesse Zugriff auf denselben Shared-Memory-Bereich haben. Er ist nicht für den Einsatz in Coroutine-Kontexten gedacht – für Coroutines sollte stattdessen Swoole\Coroutine\Channel verwendet werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $size Pflicht | int | Größe des Shared-Memory-Puffers in Bytes. Dieser Wert legt die maximale Kapazität des Kanals fest und kann nach der Erstellung nicht mehr verändert werden. Empfohlen werden Vielfache von 4096. |
Rückgabewert
Beispiele
Einfache prozessübergreifende Kommunikation mit push/pop
<?php
// Kanal mit 64 KB Puffer erstellen (vor fork!)
$channel = new Swoole\Channel(1024 * 64);
$pid = pcntl_fork();
if ($pid === 0) {
// Kind-Prozess: Daten in den Kanal schreiben
$data = ['message' => 'Hallo vom Kind-Prozess', 'timestamp' => time()];
$channel->push($data);
echo "Kind: Daten gesendet.\n";
exit(0);
} else {
// Master-Prozess: kurz warten, dann Daten lesen
sleep(1);
$received = $channel->pop();
echo "Master empfangen: " . $received['message'] . "\n";
pcntl_wait($status);
}
Verwendung mit Swoole\Process für Worker-Pool
<?php
// Kanal mit 256 KB Puffer
$channel = new Swoole\Channel(1024 * 256);
$workers = [];
for ($i = 0; $i < 3; $i++) {
$process = new Swoole\Process(function (Swoole\Process $worker) use ($channel, $i) {
// Jeder Worker schreibt eine Aufgabe in den Kanal
$task = "Ergebnis von Worker #{$i}: " . rand(100, 999);
$channel->push($task);
echo "Worker #{$i} hat Daten gesendet.\n";
});
$process->start();
$workers[] = $process;
}
// Auf alle Worker warten
foreach ($workers as $worker) {
Swoole\Process::wait();
}
// Alle Ergebnisse aus dem Kanal lesen
for ($i = 0; $i < 3; $i++) {
$result = $channel->pop();
echo "Gelesen: {$result}\n";
}
// Wichtig · Fallstricke
Wichtige Hinweise:
- Der Kanal muss zwingend vor dem Aufruf von
pcntl_fork()oderSwoole\Process::start()erstellt werden, damit alle Prozesse denselben Shared-Memory-Bereich nutzen. - Wenn der Puffer voll ist, blockiert
push()so lange, bis ein anderer Prozess Daten mitpop()entnimmt. Achte darauf, Deadlocks zu vermeiden. pop()blockiert, wenn der Kanal leer ist, bis neue Daten verfügbar sind. Dies kann in bestimmten Szenarien zu Hängeern führen.- Für den Einsatz in Coroutines ist
Swoole\Coroutine\Channelzu bevorzugen, daSwoole\Channelnicht coroutine-aware ist und den Event Loop blockieren kann. - PHP-Arrays und Objekte werden intern automatisch serialisiert/deserialisiert, was bei sehr großen Datenstrukturen zu Performance-Einbußen führen kann.
- Der maximale Puffer ist durch den beim Erstellen angegebenen
size-Wert begrenzt. Eine einzelne Nachricht darf diese Größe nicht überschreiten.