Signatur
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;
}
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);
}
// 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.