Start · Sprachen · PHP · Referenz · SyncSemaphore

SyncSemaphore

Klasse

Repräsentiert ein benanntes Semaphor zur Synchronisation von Prozessen und Threads über PECL-Sync.

seit PHP 1.0.0 Kategorie: misc

Signatur

class SyncSemaphore

Beschreibung

SyncSemaphore ist Teil der PECL-Sync-Erweiterung und implementiert ein klassisches Semaphor-Objekt, das systemweit (also auch prozessübergreifend) verwendet werden kann. Ein Semaphor verwaltet intern einen Zähler und erlaubt es, eine bestimmte Anzahl gleichzeitiger Zugriffe auf eine gemeinsame Ressource zu koordinieren.

Im Gegensatz zu einem einfachen Mutex (der nur einen einzigen exklusiven Zugriff erlaubt) kann ein Semaphor so konfiguriert werden, dass mehrere Prozesse gleichzeitig Zugriff erhalten – bis zu einem definierten Maximum. Sobald das Maximum erreicht ist, müssen weitere Prozesse warten, bis ein anderer Prozess seinen Slot wieder freigibt.

Typische Anwendungsfälle sind die Begrenzung paralleler Datenbankverbindungen, das Throttling von API-Zugriffen oder das Koordinieren mehrerer Worker-Prozesse, die auf eine begrenzte Ressource zugreifen sollen. Der Name des Semaphors ermöglicht es verschiedenen PHP-Prozessen, sich auf dasselbe Synchronisationsobjekt zu beziehen.

Wichtig: Die Erweiterung muss über PECL installiert sein (pecl install sync). Unter Windows werden benannte System-Semaphore genutzt, unter Linux/macOS POSIX-Semaphore.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Eindeutiger, systemweiter Name des Semaphors. Unter Windows wird dem Namen automatisch ein Präfix vorangestellt. Unter Linux/macOS wird der Name als POSIX-Semaphor-Bezeichner verwendet.
$initialval int 1 Anfangswert (Kapazität) des Semaphors. Gibt an, wie viele gleichzeitige Locks maximal gewährt werden. Der Wert 1 entspricht einem Mutex-Verhalten.
$autounlock bool true Gibt an, ob das Semaphor automatisch freigegeben werden soll, wenn das Objekt zerstört wird. Bei true wird ein noch gehaltenes Lock beim Aufräumen automatisch freigegeben.

Beispiele

Einfache Nutzung als Mutex (exklusiver Zugriff)

<?php
// Semaphor mit Kapazität 1 = exklusiver Zugriff (Mutex-Verhalten)
$sem = new SyncSemaphore('MeinSemaphor', 1, true);

// Lock anfordern (blockiert, bis der Slot verfügbar ist)
if ($sem->lock(3000)) { // Timeout: 3000 ms
    try {
        // Kritischer Abschnitt
        echo 'Exklusiver Zugriff erhalten.' . PHP_EOL;
        sleep(1); // Arbeit simulieren
    } finally {
        // Lock wieder freigeben
        $sem->unlock();
        echo 'Lock freigegeben.' . PHP_EOL;
    }
} else {
    echo 'Timeout: Konnte Lock nicht erhalten.' . PHP_EOL;
}
Exklusiver Zugriff erhalten. Lock freigegeben.

Semaphor mit mehreren erlaubten gleichzeitigen Zugriffen

<?php
// Maximal 3 parallele Worker erlaubt
$sem = new SyncSemaphore('DatenbankPool', 3, true);

function doWork(SyncSemaphore $sem, int $workerId): void {
    if ($sem->lock(5000)) {
        try {
            echo "Worker {$workerId}: Slot erhalten, verarbeite..." . PHP_EOL;
            usleep(500000); // 0,5 Sekunden Arbeit simulieren
        } finally {
            $sem->unlock();
            echo "Worker {$workerId}: Slot freigegeben." . PHP_EOL;
        }
    } else {
        echo "Worker {$workerId}: Timeout beim Warten auf Slot." . PHP_EOL;
    }
}

// Simuliere mehrere sequenzielle Worker-Aufrufe im selben Prozess
for ($i = 1; $i <= 4; $i++) {
    doWork($sem, $i);
}
Worker 1: Slot erhalten, verarbeite... Worker 1: Slot freigegeben. Worker 2: Slot erhalten, verarbeite... Worker 2: Slot freigegeben. Worker 3: Slot erhalten, verarbeite... Worker 3: Slot freigegeben. Worker 4: Slot erhalten, verarbeite... Worker 4: Slot freigegeben.

// Wichtig · Fallstricke

PECL-Abhängigkeit: SyncSemaphore ist nicht Teil von PHP-Core, sondern der PECL-Erweiterung sync. Sie muss separat installiert und in der php.ini aktiviert werden (extension=sync).

Deadlock-Gefahr: Wenn ein Prozess abstürzt, ohne das Semaphor freizugeben, und autounlock auf false gesetzt ist, kann es zu einem Deadlock kommen. Es empfiehlt sich, autounlock = true zu verwenden und Locks stets in einem try/finally-Block zu halten.

Plattformunterschiede: Unter Windows werden benannte Kernel-Objekte verwendet. Unter Linux/macOS kommen POSIX-Semaphore zum Einsatz. Die Namen sollten daher nur alphanumerische Zeichen und Unterstriche enthalten, um maximale Portabilität zu gewährleisten.

Timeout-Parameter: Die Methode lock() akzeptiert einen optionalen Timeout-Wert in Millisekunden. Wird -1 übergeben, wartet der Aufruf unbegrenzt.