Start · Sprachen · PHP · Referenz · wincache_lock

wincache_lock

Funktion

Erlangt eine exklusive Sperre (Lock) für einen angegebenen Schlüssel im WinCache-Shared-Memory, um gleichzeitige Zugriffe zu koordinieren.

seit PHP 1.1.0 Kategorie: misc

Signatur

wincache_lock(string $key, bool $isglobal = false): bool

Beschreibung

wincache_lock() ist eine Funktion der WinCache-Erweiterung für PHP unter Windows und ermöglicht es, einen benannten, exklusiven Lock auf einen Schlüssel zu setzen. Solange ein Prozess oder Thread diesen Lock hält, können andere Prozesse denselben Lock nicht erlangen – sie warten blockierend, bis der Lock freigegeben wird. Dies ist nützlich, um kritische Abschnitte (Race Conditions) bei gleichzeitigen Zugriffen auf geteilte Ressourcen zu verhindern.

Ein typischer Anwendungsfall ist das atomare Lesen-Modifizieren-Schreiben von Werten im WinCache-Benutzercache: Vor der Lese-/Schreiboperation wird der Lock gesetzt, die Operation wird durchgeführt, und anschließend wird der Lock mit wincache_unlock() wieder freigegeben. Ohne diesen Mechanismus könnten parallele PHP-Requests inkonsistente Zustände erzeugen.

Der Parameter isglobal steuert, ob der Lock über FastCGI-Prozessgrenzen hinweg gilt (true) oder nur innerhalb eines einzelnen FastCGI-Prozesses (false, Standard). Bei Anwendungen mit mehreren FastCGI-Prozessen sollte true verwendet werden, um den Lock wirklich global zu machen.

Wichtig: Der Lock muss nach Gebrauch immer mit wincache_unlock() freigegeben werden, da er sonst zu einem Deadlock führen kann. Ein try/finally-Block ist daher empfehlenswert.

Parameter

Name Typ Default Beschreibung
$key Pflicht string Der Name des Schlüssels, für den die exklusive Sperre erlangt werden soll. Der Schlüsselname ist frei wählbar und muss nicht im WinCache vorhanden sein.
$isglobal bool false Gibt an, ob der Lock global (über alle FastCGI-Prozesse) oder nur lokal (innerhalb eines einzelnen FastCGI-Prozesses) gelten soll. Für Multiprocess-Szenarien sollte true verwendet werden.

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Sperre erfolgreich erlangt wurde, andernfalls false.

Beispiele

Atomares Inkrementieren eines Cache-Zählers

<?php
$key = 'page_view_counter';

// Exklusive Sperre setzen (global über alle FastCGI-Prozesse)
if (wincache_lock($key, true)) {
    try {
        // Aktuellen Wert lesen
        $count = wincache_ucache_get($key);
        if ($count === false) {
            $count = 0;
        }
        // Wert inkrementieren und speichern
        $count++;
        wincache_ucache_set($key, $count);
        echo 'Seitenaufrufe: ' . $count;
    } finally {
        // Sperre in jedem Fall freigeben
        wincache_unlock($key);
    }
} else {
    echo 'Konnte Sperre nicht erlangen.';
}
Seitenaufrufe: 1

Schutz eines kritischen Abschnitts mit lokalem Lock

<?php
$lockKey = 'order_processing_lock';

if (wincache_lock($lockKey)) {
    try {
        // Kritischer Abschnitt: z. B. Bestellung verarbeiten
        $orders = wincache_ucache_get('pending_orders');
        if (!empty($orders)) {
            $nextOrder = array_shift($orders);
            wincache_ucache_set('pending_orders', $orders);
            echo 'Verarbeite Bestellung: ' . $nextOrder['id'];
        } else {
            echo 'Keine offenen Bestellungen.';
        }
    } finally {
        wincache_unlock($lockKey);
    }
} else {
    echo 'Lock konnte nicht gesetzt werden.';
}
Verarbeite Bestellung: 42

// Wichtig · Fallstricke

Deadlock-Gefahr: Wenn wincache_unlock() nicht aufgerufen wird (z. B. durch eine nicht abgefangene Ausnahme), bleibt der Lock bestehen und blockiert alle anderen Prozesse, die denselben Lock anfordern. Verwende daher immer einen try/finally-Block, um den Lock sicher freizugeben.

Plattformbeschränkung: WinCache und damit auch wincache_lock() sind ausschließlich auf Windows-Systemen verfügbar. Der Einsatz auf Linux- oder macOS-Systemen ist nicht möglich.

Alternative: Für plattformübergreifende Lock-Mechanismen kann sem_acquire() (POSIX-Semaphore) oder dateibasiertes Locking mit flock() verwendet werden.