Signatur
Beschreibung
SyncReaderWriter ist eine Klasse aus der PECL-Erweiterung sync und implementiert eine klassische Reader-Writer-Sperre (auch Read-Write-Lock genannt). Sie erlaubt es, dass mehrere Prozesse oder Threads gleichzeitig lesend auf eine gemeinsame Ressource zugreifen, während Schreibzugriffe exklusiv und gegenseitig ausschließend sind.
Das Konzept dahinter: Solange kein Schreiber aktiv ist, können beliebig viele Leser gleichzeitig die Sperre halten. Sobald ein Schreiber die Sperre anfordert oder hält, werden alle weiteren Leser und Schreiber blockiert, bis der Schreiber fertig ist. Dies maximiert den Durchsatz bei leseintensiven Workloads und schützt gleichzeitig vor inkonsistenten Zuständen bei Schreiboperationen.
Typische Anwendungsfälle sind gemeinsam genutzte Konfigurationsdaten, Caches oder andere Ressourcen, die häufig gelesen, aber selten geschrieben werden. Die Sperre kann benannt werden, sodass auch voneinander unabhängige PHP-Prozesse dieselbe Sperre verwenden können.
Um die Klasse zu nutzen, muss die PECL-Erweiterung sync installiert sein. Unter Windows werden Mutex-basierte Sperren verwendet, unter Unix/Linux POSIX-Semaphoren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name | string | Optionaler Name der Sperre. Wird ein Name angegeben, kann dieselbe Sperre prozessübergreifend verwendet werden. Ohne Namen ist die Sperre nur innerhalb desselben Prozesses nutzbar. | |
| $autounlock | bool | true | Gibt an, ob die Sperre automatisch freigegeben werden soll, wenn das Objekt zerstört wird. Ist autounlock auf false gesetzt, bleibt die Sperre auch nach der Objektzerstörung aktiv, was zu Deadlocks führen kann. |
Beispiele
Lesezugriff mit ReadLock
<?php
// Benannte Reader-Writer-Sperre erzeugen
$rw = new SyncReaderWriter('my_shared_resource');
// Lesesperre anfordern (mehrere Leser gleichzeitig möglich)
if ($rw->readlock()) {
try {
// Lesenden Zugriff auf die gemeinsame Ressource
echo 'Lese gemeinsame Daten...' . PHP_EOL;
// ... Leseoperationen hier ...
} finally {
// Lesesperre immer freigeben
$rw->readunlock();
}
} else {
echo 'Konnte Lesesperre nicht erwerben.' . PHP_EOL;
}
Exklusiver Schreibzugriff mit WriteLock
<?php
// Benannte Reader-Writer-Sperre erzeugen
$rw = new SyncReaderWriter('my_shared_resource');
// Schreibsperre anfordern (exklusiver Zugriff)
if ($rw->writelock()) {
try {
// Exklusiven Schreibzugriff ausführen
echo 'Schreibe gemeinsame Daten...' . PHP_EOL;
// ... Schreiboperationen hier ...
} finally {
// Schreibsperre immer freigeben
$rw->writeunlock();
}
} else {
echo 'Konnte Schreibsperre nicht erwerben.' . PHP_EOL;
}
Timeout bei der Sperranforderung
<?php
// Reader-Writer-Sperre mit Timeout
$rw = new SyncReaderWriter('my_shared_resource');
// Versuche, Lesesperre innerhalb von 2000 ms zu erwerben
if ($rw->readlock(2000)) {
echo 'Lesesperre erworben.' . PHP_EOL;
// ... Leseoperationen ...
$rw->readunlock();
} else {
echo 'Timeout: Lesesperre konnte nicht erworben werden.' . PHP_EOL;
}
// Wichtig · Fallstricke
Achtung vor Deadlocks: Wird autounlock auf false gesetzt und die Sperre nicht explizit freigegeben, kann dies zu Deadlocks führen, die andere Prozesse dauerhaft blockieren.
Schreiber-Hunger (Writer Starvation): In Szenarien mit sehr vielen gleichzeitigen Lesern kann ein Schreiber lange auf seine Sperre warten müssen. Planen Sie dies in der Architektur Ihrer Anwendung ein.
Plattformunterschiede: Die interne Implementierung unterscheidet sich zwischen Windows (Mutex/Events) und Unix/Linux (POSIX-Semaphoren). Das Verhalten bei Prozessabbrüchen kann sich daher je nach Plattform unterscheiden.
Die Klasse ist nicht Teil der PHP-Standardbibliothek, sondern erfordert die Installation der PECL-Erweiterung sync.