Signatur
Beschreibung
Worker ist eine Kernklasse der pthreads-Erweiterung und erweitert Thread um eine eingebaute Aufgabenwarteschlange. Im Gegensatz zu einem einfachen Thread, der nach dem Ausführen seiner run()-Methode beendet wird, bleibt ein Worker am Leben und wartet auf neue Aufgaben, die ihm mit stack() übergeben werden.
Typischer Einsatz: Ein Worker-Thread wird gestartet und anschließend werden ihm via stack() mehrere Threaded-Objekte (die eigentliche Arbeit) übergeben. Der Worker führt jede gestapelte Aufgabe der Reihe nach aus, ohne den Thread neu starten zu müssen – das spart den Overhead der Thread-Erstellung bei wiederkehrenden Aufgaben erheblich.
Die Methode run() im Worker dient als optionaler Initialisierungsschritt, der einmal beim Start des Threads ausgeführt wird (z. B. Datenbankverbindung herstellen). Die eigentliche Arbeit findet in den run()-Methoden der gestapelten Threaded-Objekte statt.
Hinweis: pthreads ist nur in der ZTS (Zend Thread Safety)-Version von PHP verfügbar und nicht für Produktivumgebungen unter PHP-FPM oder Apache mod_php geeignet. Ab PHP 8 wird pthreads durch parallel abgelöst.
Rückgabewert
Beispiele
Einfacher Worker mit gestapelten Aufgaben
<?php
// Aufgaben-Klasse: jede Instanz repräsentiert eine einzelne Aufgabe
class Task extends Threaded {
private string $name;
public function __construct(string $name) {
$this->name = $name;
}
public function run(): void {
echo "Aufgabe '{$this->name}' wird ausgeführt in Thread-ID: " . Thread::getCurrentThreadId() . PHP_EOL;
sleep(1); // simulierte Arbeit
}
}
// Worker-Klasse mit optionalem Initialisierungs-Code
class MyWorker extends Worker {
public function run(): void {
echo "Worker gestartet, bereit für Aufgaben." . PHP_EOL;
}
}
$worker = new MyWorker();
$worker->start();
// Aufgaben in die Warteschlange des Workers stapeln
$worker->stack(new Task('Alpha'));
$worker->stack(new Task('Beta'));
$worker->stack(new Task('Gamma'));
// Warten bis alle Aufgaben abgearbeitet sind, dann Worker beenden
$worker->shutdown();
echo "Alle Aufgaben erledigt." . PHP_EOL;
Worker-Pool mit mehreren Workern (einfaches Worker-Pool-Muster)
<?php
class DownloadTask extends Threaded {
private string $url;
public function __construct(string $url) {
$this->url = $url;
}
public function run(): void {
// Simulierter Download
echo "Lade herunter: {$this->url}" . PHP_EOL;
usleep(500000);
echo "Fertig: {$this->url}" . PHP_EOL;
}
}
class DownloadWorker extends Worker {
public function run(): void {
// Ressourcen initialisieren (z. B. cURL-Handle)
echo "DownloadWorker bereit." . PHP_EOL;
}
}
$urls = [
'https://example.com/file1',
'https://example.com/file2',
'https://example.com/file3',
'https://example.com/file4',
];
$workerCount = 2;
$workers = [];
// Mehrere Worker starten
for ($i = 0; $i < $workerCount; $i++) {
$workers[$i] = new DownloadWorker();
$workers[$i]->start();
}
// Aufgaben reihum auf die Worker verteilen
foreach ($urls as $index => $url) {
$workers[$index % $workerCount]->stack(new DownloadTask($url));
}
// Alle Worker beenden
foreach ($workers as $worker) {
$worker->shutdown();
}
echo "Alle Downloads abgeschlossen." . PHP_EOL;
// Wichtig · Fallstricke
Methoden im Überblick:
stack(Threaded $work): int– Fügt einThreaded-Objekt am Ende der Warteschlange hinzu. Rückgabe: Anzahl der aktuell gestapelten Aufgaben.unstack(): int– Entfernt die erste (nächste) Aufgabe aus der Warteschlange und gibt die verbleibende Anzahl zurück.getStacked(): int– Gibt die Anzahl der aktuell gestapelten (noch nicht ausgeführten) Aufgaben zurück.shutdown(): bool– Wartet, bis alle gestapelten Aufgaben abgearbeitet wurden, und beendet den Worker-Thread dann sauber. Wichtig: Immershutdown()stattjoin()verwenden, dajoin()sofort terminiert, ohne die Warteschlange zu leeren.isShutdown(): bool– Gibt an, obshutdown()bereits aufgerufen wurde.
Verfügbarkeit: pthreads benötigt eine ZTS-PHP-Kompilierung (--enable-maintainer-zts). Es funktioniert nur in CLI-SAPI und ist nicht kompatibel mit PHP-FPM, mod_php oder anderen nicht-thread-sicheren SAPIs.
Ab PHP 8: pthreads wird nicht mehr aktiv weiterentwickelt. Für parallele Verarbeitung in PHP 8+ wird die parallel-Erweiterung mit parallel\Runtime und parallel\Channel empfohlen.