Start · Sprachen · PHP · Referenz · Collectable

Collectable

Interface

Repräsentiert eine Aufgabe, die von einem <code>Worker</code> oder <code>Pool</code> in der pthreads-Erweiterung ausgeführt werden kann.

seit PHP 1.0.0 Kategorie: oop

Signatur

interface Collectable

Beschreibung

Collectable ist ein Interface aus der pthreads-Erweiterung (ab v3 auch in parallel). Es markiert Objekte, die als Arbeitseinheiten in einem Worker oder Pool eingereiht und nach ihrer Ausführung wieder eingesammelt (engl. collected) werden können. Klassen, die in einem Pool::submit()-Aufruf übergeben werden sollen, müssen dieses Interface implementieren.

Das Interface erzwingt die Implementierung der Methode isGarbage(), mit der der Pool entscheidet, ob ein abgeschlossenes Task-Objekt entfernt werden darf. Sobald isGarbage() den Wert true zurückgibt, kann der Pool den Speicher für dieses Objekt freigeben. Dies erlaubt eine feingranulare Kontrolle über den Lebenszyklus parallel ausgeführter Aufgaben.

Typischerweise erbt die eigene Task-Klasse von Threaded und implementiert zusätzlich Collectable. In der Methode run() wird die eigentliche Arbeit erledigt, und isGarbage() signalisiert dem Pool, wann die Aufgabe abgeschlossen und nicht mehr benötigt wird.

  • Geeignet für parallele Verarbeitungsszenarien wie Batch-Verarbeitung, asynchrone I/O-Aufgaben oder CPU-intensive Berechnungen.
  • Nur in Kombination mit der pthreads-Erweiterung (PHP CLI, Thread-sichere Builds) verwendbar.

Beispiele

Einfache Task-Klasse mit Collectable

<?php
// Voraussetzung: pthreads-Erweiterung installiert (Thread-sicheres PHP-CLI-Build)

class MyTask extends Threaded implements Collectable
{
    private bool $done = false;
    private string $input;

    public function __construct(string $input)
    {
        $this->input = $input;
    }

    public function run(): void
    {
        // Eigentliche Arbeit der Aufgabe
        echo "Verarbeite: " . strtoupper($this->input) . PHP_EOL;
        $this->done = true;
    }

    public function isGarbage(): bool
    {
        // Gibt true zurück, sobald die Aufgabe abgeschlossen ist
        return $this->done;
    }
}

$pool = new Pool(4); // Pool mit 4 Worker-Threads

foreach (['alpha', 'beta', 'gamma'] as $item) {
    $pool->submit(new MyTask($item));
}

$pool->shutdown();
$pool->collect();

echo "Alle Aufgaben abgeschlossen." . PHP_EOL;
Verarbeite: ALPHA Verarbeite: BETA Verarbeite: GAMMA Alle Aufgaben abgeschlossen.

Manuelle Garbage-Collection mit collect()

<?php
// Voraussetzung: pthreads-Erweiterung

class ComputeTask extends Threaded implements Collectable
{
    private bool $finished = false;
    public int $result = 0;
    private int $value;

    public function __construct(int $value)
    {
        $this->value = $value;
    }

    public function run(): void
    {
        // Simuliert eine aufwändige Berechnung
        $this->result = $this->value ** 2;
        $this->finished = true;
    }

    public function isGarbage(): bool
    {
        return $this->finished;
    }
}

$pool = new Pool(2);

for ($i = 1; $i <= 5; $i++) {
    $pool->submit(new ComputeTask($i));
}

$pool->shutdown();

// Einsammeln abgeschlossener Objekte (gibt Speicher frei)
$pool->collect(function (ComputeTask $task): bool {
    echo "Ergebnis: " . $task->result . PHP_EOL;
    return $task->isGarbage();
});

$pool->shutdown();
Ergebnis: 1 Ergebnis: 4 Ergebnis: 9 Ergebnis: 16 Ergebnis: 25

// Wichtig · Fallstricke

Achtung: Die pthreads-Erweiterung erfordert zwingend einen Thread-sicheren PHP-Build (ZTS – Zend Thread Safety) und ist nur im CLI-Modus nutzbar. Sie ist nicht für PHP-FPM oder Apache-Module geeignet. Ab PHP 8.x wird pthreads kaum noch aktiv weiterentwickelt; als modernere Alternative bietet sich die parallel-Erweiterung an.

Wird isGarbage() niemals true zurückgeben, sammelt der Pool die Objekte nicht ein, was zu Speicherlecks führen kann. Stelle sicher, dass isGarbage() zuverlässig nach Abschluss der Aufgabe true zurückgibt.

Siehe auch