Start · Sprachen · PHP · Referenz · Volatile

Volatile

Klasse

Repräsentiert ein veränderliches, zwischen Threads geteiltes Objekt, dessen Eigenschaften zur Laufzeit geändert werden können.

seit PHP 3.0.0 Kategorie: oop

Signatur

class Volatile extends Threaded implements Collectable, Traversable

Beschreibung

Volatile ist eine Klasse aus der pthreads-Erweiterung und dient als Basisklasse für Objekte, die zwischen mehreren Threads geteilt werden und deren Eigenschaften auch nach der Übergabe an einen anderen Thread noch veränderlich (mutable) sein sollen.

In pthreads v3 wurde das Verhalten von Threaded-Objekten dahingehend geändert, dass deren Eigenschaften nach der Übergabe an einen Thread standardmäßig als immutable behandelt werden – um Dateninkonsistenz zu vermeiden. Volatile hebt diese Einschränkung auf: Eigenschaften eines Volatile-Objekts können auch von mehreren Threads aus geschrieben werden. Dies ist besonders nützlich für gemeinsam genutzte Datenstrukturen wie Arrays oder Queues, die dynamisch befüllt werden.

Typische Anwendungsfälle sind geteilte Zähler, gemeinsame Listen oder Konfigurationsobjekte, die von Worker-Threads gelesen und geschrieben werden. Der Zugriff auf Eigenschaften eines Volatile-Objekts wird intern durch ein Mutex geschützt, sodass keine explizite Synchronisation notwendig ist.

Hinweis: Die pthreads-Erweiterung ist nur in PHP CLI verfügbar und wird seit pthreads v4 (für PHP 8) durch parallel ersetzt. Für neue Projekte empfiehlt sich die Verwendung der parallel-Erweiterung.

Parameter

Name Typ Default Beschreibung
$value mixed Optionaler Initialwert, der dem Volatile-Objekt übergeben werden kann. In der Regel werden Eigenschaften nach der Instanziierung gesetzt.

Rückgabewert

Typ

Beispiele

Geteilte Ergebnisliste zwischen Worker-Threads

<?php
// Requires pthreads extension (PHP CLI only)

class Worker extends Thread
{
    private Volatile $results;
    private int $id;

    public function __construct(Volatile $results, int $id)
    {
        $this->results = $results;
        $this->id      = $id;
    }

    public function run(): void
    {
        // Ergebnis in das geteilte Volatile-Objekt schreiben
        $this->results[] = 'Ergebnis von Thread ' . $this->id;
    }
}

$results = new Volatile();

$threads = [];
for ($i = 1; $i <= 3; $i++) {
    $threads[$i] = new Worker($results, $i);
    $threads[$i]->start();
}

foreach ($threads as $thread) {
    $thread->join();
}

foreach ($results as $result) {
    echo $result . PHP_EOL;
}
Ergebnis von Thread 1 Ergebnis von Thread 2 Ergebnis von Thread 3

Volatile als veränderlicher geteilter Zähler

<?php
// Requires pthreads extension (PHP CLI only)

class Counter extends Thread
{
    private Volatile $shared;

    public function __construct(Volatile $shared)
    {
        $this->shared = $shared;
    }

    public function run(): void
    {
        // Synchronized schützt den kritischen Abschnitt
        $this->shared->synchronized(function (Volatile $shared) {
            $shared->count = ($shared->count ?? 0) + 1;
        }, $this->shared);
    }
}

$shared = new Volatile();
$shared->count = 0;

$threads = [];
for ($i = 0; $i < 5; $i++) {
    $threads[] = new Counter($shared);
    $threads[$i]->start();
}

foreach ($threads as $thread) {
    $thread->join();
}

echo 'Zählerstand: ' . $shared->count . PHP_EOL;
Zählerstand: 5

// Wichtig · Fallstricke

Wichtig: Volatile ist Teil der pthreads-Erweiterung, die nur in PHP CLI (Kommandozeile) funktioniert – nicht in PHP-FPM oder Apache-Modulen. Der Einsatz in Web-Servern führt zu undefinierten Zuständen.

Thread-Sicherheit: Auch wenn Volatile-Eigenschaften thread-sicher gelesen und geschrieben werden können, sind zusammengesetzte Operationen (z. B. Lesen-Inkrementieren-Schreiben) nicht atomar. Verwende in solchen Fällen unbedingt synchronized(), um Race Conditions zu vermeiden.

Deprecation: pthreads wird nicht mehr aktiv weiterentwickelt und unterstützt nur PHP 7.x (bis pthreads 3.x). Für PHP 8+ sollte die parallel-Erweiterung genutzt werden, die kein direktes Äquivalent zu Volatile kennt, aber mit parallel\Channel und parallel\Future ähnliche Muster ermöglicht.