Signatur
Beschreibung
sem_release gibt einen Semaphor frei, der zuvor mit sem_acquire gesperrt wurde. Dies ermöglicht anderen Prozessen oder Threads, den Semaphor zu akquirieren und auf die geschützte Ressource zuzugreifen. Die Funktion ist Teil der System-V-Semaphor-API unter Unix/Linux.
Semaphore werden typischerweise zur Synchronisation paralleler Prozesse eingesetzt – etwa um sicherzustellen, dass nur ein Prozess gleichzeitig eine kritische Sektion ausführt (Mutual Exclusion). Nachdem der kritische Abschnitt abgeschlossen ist, muss der Semaphor explizit mit sem_release freigegeben werden.
Wichtig: Pro Semaphor-Handle kann ein Prozess den Semaphor mehrfach akquirieren (bis zur bei sem_get definierten Maximalanzahl). Jeder Aufruf von sem_release erhöht den internen Zähler um 1. Ein Semaphor sollte immer exakt so oft freigegeben werden, wie er akquiriert wurde, sonst kommt es zu Deadlocks oder Ressourcenlecks.
Die Funktion ist nur auf Unix-ähnlichen Betriebssystemen verfügbar und setzt voraus, dass PHP mit System-V-Semaphor-Unterstützung kompiliert wurde (--enable-sysvsem).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $semaphore Pflicht | SysvSemaphore | Ein Semaphor-Handle, das mit sem_get erzeugt und zuvor mit sem_acquire gesperrt wurde. |
Rückgabewert
true zurück, wenn der Semaphor erfolgreich freigegeben wurde. Gibt false zurück, wenn ein Fehler auftritt – z. B. wenn der aufrufende Prozess den Semaphor gar nicht besitzt oder das Handle ungültig ist.Beispiele
Einfache kritische Sektion mit Semaphor absichern
<?php
// Semaphor erzeugen (Schlüssel 12345, max. 1 Prozess gleichzeitig)
$semaphore = sem_get(12345, 1);
if ($semaphore === false) {
die('Semaphor konnte nicht erzeugt werden.');
}
// Semaphor akquirieren (blockiert, bis er verfügbar ist)
if (sem_acquire($semaphore)) {
echo 'Kritische Sektion wird ausgeführt...' . PHP_EOL;
// Simulierter exklusiver Zugriff auf eine Ressource
sleep(2);
echo 'Kritische Sektion abgeschlossen.' . PHP_EOL;
// Semaphor wieder freigeben
sem_release($semaphore);
} else {
echo 'Semaphor konnte nicht akquiriert werden.' . PHP_EOL;
}
Semaphor mit Fehlerbehandlung und Aufräumen
<?php
$key = ftok('/tmp/myapp.lock', 'A');
$semaphore = sem_get($key, 1, 0600, 1);
if ($semaphore === false) {
die('Semaphor konnte nicht erstellt werden.');
}
try {
if (!sem_acquire($semaphore)) {
throw new RuntimeException('Semaphor konnte nicht akquiriert werden.');
}
// Geschützter Bereich: z. B. Schreiben in eine Datei
file_put_contents('/tmp/shared_resource.txt', date('Y-m-d H:i:s') . ': Eintrag\n', FILE_APPEND);
echo 'Eintrag erfolgreich geschrieben.' . PHP_EOL;
} finally {
// Semaphor in jedem Fall freigeben (auch bei Ausnahme)
sem_release($semaphore);
echo 'Semaphor freigegeben.' . PHP_EOL;
}
// Wichtig · Fallstricke
Plattformabhängigkeit: sem_release ist nur unter Unix/Linux verfügbar. Unter Windows steht diese Funktion nicht zur Verfügung.
Deadlock-Gefahr: Wenn ein Prozess sem_release nicht aufruft (z. B. durch einen unbehandelten Fehler oder Absturz), bleibt der Semaphor blockiert. Andere Prozesse warten dann unbegrenzt. Die Verwendung von try/finally-Blöcken ist daher dringend empfohlen.
Mehrfaches Akquirieren: Wurde ein Semaphor mehrfach mit sem_acquire gesperrt, muss er ebenso oft mit sem_release freigegeben werden, da jeder Aufruf den Zähler nur um 1 erhöht.
Löschen des Semaphors: Mit sem_remove kann ein Semaphor vollständig aus dem System entfernt werden. Dies sollte nur dann geschehen, wenn kein anderer Prozess mehr auf ihn wartet.