QLockFile Class
Die Klasse „QLockFile“ ermöglicht die Sperrung zwischen Prozessen mithilfe einer Datei. Mehr...
| Header: | #include <QLockFile> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QLockFile ist Teil von „Eingabe/Ausgabe und Netzwerk“.
Öffentliche Typen
| enum | LockError { NoError, LockFailedError, PermissionError, UnknownError } |
Öffentliche Funktionen
| QLockFile(const QString &fileName) | |
| ~QLockFile() | |
| QLockFile::LockError | error() const |
| QString | fileName() const |
| bool | getLockInfo(qint64 *pid, QString *hostname, QString *appname) const |
| bool | isLocked() const |
| bool | lock() |
| bool | removeStaleLockFile() |
| void | setStaleLockTime(int staleLockTime) |
(since 6.2) void | setStaleLockTime(std::chrono::milliseconds staleLockTime) |
| int | staleLockTime() const |
(since 6.2) std::chrono::milliseconds | staleLockTimeAsDuration() const |
| bool | tryLock(int timeout) |
(since 6.2) bool | tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero()) |
| void | unlock() |
Ausführliche Beschreibung
Eine Sperrdatei kann verwendet werden, um zu verhindern, dass mehrere Prozesse gleichzeitig auf dieselbe Ressource zugreifen. Beispielsweise auf eine Konfigurationsdatei auf der Festplatte, einen Socket, einen Port oder einen Bereich des gemeinsam genutzten Speichers...
Die Serialisierung ist nur dann gewährleistet, wenn alle Prozesse, die auf die gemeinsam genutzte Ressource zugreifen, „QLockFile“ mit demselben Dateipfad verwenden.
QLockFile unterstützt zwei Anwendungsfälle: den Schutz einer Ressource für einen kurzfristigen Vorgang (z. B. die Überprüfung, ob sich eine Konfigurationsdatei geändert hat, bevor neue Einstellungen gespeichert werden) und den langfristigen Schutz einer Ressource (z. B. eines von einem Benutzer in einem Editor geöffneten Dokuments) für einen unbestimmten Zeitraum.
Beim Schutz für einen kurzfristigen Vorgang ist es zulässig, ` lock()` aufzurufen und zu warten, bis alle laufenden Vorgänge abgeschlossen sind. Beim langfristigen Schutz einer Ressource sollte die Anwendung jedoch immer ` setStaleLockTime(0ms)` und anschließend ` tryLock()` mit einer kurzen Zeitüberschreitung aufrufen, um den Benutzer darauf hinzuweisen, dass die Ressource gesperrt ist.
Wenn der Prozess, der die Sperre hält, abstürzt, verbleibt die Sperrdatei auf der Festplatte und kann verhindern, dass andere Prozesse jemals auf die gemeinsam genutzte Ressource zugreifen. Aus diesem Grund versucht QLockFile, eine solche „veraltete“ Sperrdatei anhand der in die Datei geschriebenen Prozess-ID zu erkennen. Um den Fall abzudecken, dass die Prozess-ID inzwischen wiederverwendet wurde, wird der aktuelle Prozessname mit dem Namen des Prozesses verglichen, der der Prozess-ID aus der Sperrdatei entspricht. Wenn sich die Prozessnamen unterscheiden, wird die Sperrdatei als veraltet betrachtet. Zusätzlich wird der Zeitpunkt der letzten Änderung der Sperrdatei (standardmäßig 30 Sekunden, für den Anwendungsfall einer kurzlebigen Operation) berücksichtigt. Wird die Sperrdatei als veraltet erkannt, wird sie gelöscht.
Für den Anwendungsfall, bei dem eine Ressource über einen längeren Zeitraum geschützt werden soll, sollten Sie daher ` setStaleLockTime(0)` aufrufen und, wenn ` tryLock()` den Wert ` LockFailedError` zurückgibt, den Benutzer darüber informieren, dass das Dokument gesperrt ist – gegebenenfalls unter Verwendung von ` getLockInfo()` für weitere Details.
Einschränkungen
Die Implementierung von `QLockFile` ist in den meisten Umgebungen und Dateisystemen in der Regel sicher. Es gibt jedoch einige Situationen, in denen fälschlicherweise angenommen wird, dass eine Sperrdatei veraltet ist, obwohl dies nicht der Fall ist, in denen eine veraltete Datei nicht erkannt wird oder bei der Sperrung ein Race-Condition auftritt. In diesem Abschnitt werden diese Probleme beschrieben.
Es gibt zwei Hauptstrategien zur Risikominderung: die Wahl eines geeigneten, von Null verschiedenen Werts für ` staleLockTime()` und die Wahl eines regulären, lokalen Dateisystems zum Speichern von Sperrdateien (wie z. B. ` /var/lock `, wenn als Root auf Unix-Systemen ausgeführt, oder das ` runtime location`). Dies ist bei bestimmten Anwendungsfällen von `QLockFile` möglicherweise nicht möglich, z. B. wenn `QLockFile` verwendet wird, um anzuzeigen, dass ein vom Benutzer angegebener Dateipfad gerade bearbeitet wird.
Nicht persistente Maschinen-IDs
QLockFile verwendet die eindeutige ID des Rechners, um zwischen einer Sperre des aktuellen Rechners und einer von einem Prozess auf einem anderen Host zu unterscheiden. Ändert sich die Maschinen-ID im Laufe der Zeit (z. B. auf Systemen mit flüchtigem Speicher, die bei jedem Systemstart eine neue ID generieren müssen), kann QLockFile nach einem Neustart nicht erkennen, dass eine Sperrdatei veraltet ist.
Umgekehrt kann die Klasse, wenn zwei verschiedene Rechner kollidierende Rechner-IDs haben (z. B. bei einem geklonten System-Image oder einer Wiederherstellung aus Backups) und QLockFile einen Netzwerkpfad bereitstellen, zu dem Schluss kommen, dass die Sperre veraltet ist, obwohl dies tatsächlich nicht der Fall ist.
Fehlen einer nativen Sperre
QLockFile verwendet betriebssystemspezifische Aufrufe, um anderen Prozessen und Threads anzuzeigen, dass die Sperre aktiv (nicht veraltet) ist, selbst über die Einstellung ` staleLockTime()` hinaus. Diese Funktionalität kann bei Dateien auf einigen vernetzten oder virtuellen Dateisystemen (wie FUSE unter Linux und macOS) fehlen, wenn verschiedene Dateisysteme für den Zugriff auf dieselbe Datei verwendet werden und die native Sperre nicht übertragen wird, oder in bestimmten Umgebungen, die die erforderlichen Systemaufrufe blockieren.
Fehlt die native Sperrunterstützung, stützt sich QLockFile ausschließlich auf das Vorhandensein, den Änderungszeitpunkt und den Inhalt der Sperrdatei selbst. In diesem Fall übernimmt QLockFile die Sperre, wenn der Prozess, der die Ressource derzeit sperrt, diese über die in ` staleLockTime()` festgelegte Zeit hinaus hält.
Vernetzte Dateisysteme
Es ist nicht festgelegt, ob die native Dateisperre in Netzwerkumgebungen unterstützt wird: Bei einigen Implementierungen wird sie für alle Clients unterstützt, die auf das Dateisystem zugreifen; bei anderen unterstützt das lokale System möglicherweise die Sperre für seine eigenen Prozesse, gibt diese Sperre jedoch nicht über das Netzwerk weiter; und bei wieder anderen gibt es selbst innerhalb eines Hosts keine native Sperre. Zudem ist es möglich, dass einige Clients an der netzwerkweiten Sperrung teilnehmen, andere hingegen nicht – und das für dieselbe Datei. Wird die Sperrung nicht netzwerkweit unterstützt, gelten für `QLockFile` die oben beschriebenen Einschränkungen, die beim Fehlen einer nativen Sperrung gelten.
Enthält die Sperrdatei zudem die Kennung eines anderen Hosts, kann `QLockFile` nicht überprüfen, ob der Prozess, der eine Sperre hält, noch läuft, und muss auf ` staleLockTime()` warten, um sich von einem unsauberen Abbruch zu erholen.
Zugriff auf unterschiedliche tatsächliche Dateien über denselben Pfad
Es ist möglich, dass zwei Prozesse unterschiedliche Ansichten des Dateisystems haben, was dazu führt, dass ein identischer Dateipfad im Dateisystem auf unterschiedliche Dateien verweist. In diesem Fall werden die beiden QLockFile-Objekte die Sperre wahrscheinlich erfolgreich erstellen, sich jedoch nicht gegenseitig ausschließen. Dies kann zu Konflikten führen, wenn die Ressource, die durch die Sperrdatei geschützt wird, weiterhin von beiden gemeinsam genutzt wird.
Diese Situation tritt am häufigsten bei Containern auf (siehe unten), ist jedoch nicht auf diese beschränkt.
Mit Containern gemeinsam genutzte Dateien
Bei einigen Container-Implementierungen ist es möglich, die Existenz bestimmter Prozesse zu verbergen (zum Beispiel die „PID-Namespace“-Funktion von Linux). Wenn ein Prozess in einem solchen Container läuft, aber die Maschinen-ID des Hostsystems oder eines anderen Containers teilt, werden zwei Prozesse in unterschiedlichen Containern (oder auf dem Host) falsche Rückschlüsse darauf ziehen, ob der sperrende Prozess noch läuft. Zudem können manche Container-Controller die Boot-ID innerhalb des Containers überschreiben, was dazu führt, dass die gestarteten Prozesse zu dem Schluss kommen, die Sperrdatei sei stets veraltet – unabhängig davon, wie aktuell ihr Zeitstempel ist.
Bei einigen anderen Implementierungen verfügen Container möglicherweise über einen temporären Speicher oder erzeugen absichtlich eine neue Maschinen-ID, um Kollisionen zu vermeiden. In diesem Fall treten bei der Anwendung die oben beschriebenen Probleme bei nicht persistenten Maschinen-IDs auf.
Die native Dateisperrung funktioniert jedoch in der Regel (vorbehaltlich der oben besprochenen Einschränkungen des Dateisystems und der Umgebung), sodass QLockFile, selbst wenn es zu dem Schluss käme, dass die Datei scheinbar veraltet ist, keine Sperrdatei übernehmen würde, die nativ gesperrt ist.
Zugriffe, die nicht dasselbe Protokoll verwenden
QLockFile kann nicht mit Änderungen an der Sperrdatei zusammenarbeiten, die außerhalb des von dieser Klasse implementierten Protokolls vorgenommen werden. Dazu gehört das Entfernen der Sperrdatei durch andere Tools wie tmpwatch und ähnliche, aber auch durch einige Virenscanner oder ähnliche Programme.
Zeitabweichung
QLockFile ist darauf angewiesen, dass der Zeitstempel der Sperrdatei korrekt ist. Wenn die Uhr vorrückt, könnte QLockFile zu dem Schluss kommen, dass eine Sperrdatei veraltet ist, obwohl dies nicht der Fall ist, und umgekehrt, wenn die Uhr zurückgeht.
Aus diesem Grund wird empfohlen, dass alle Systeme eine netzwerksynchronisierte Zeit führen und diese Synchronisation frühzeitig im Boot-Prozess durchführen. Dies ist besonders wichtig für vernetzte Dateisysteme.
Dokumentation zu Mitgliedstypen
enum QLockFile::LockError
Diese Enumeration beschreibt das Ergebnis des letzten Aufrufs von ` lock()` oder ` tryLock()`.
| Konstante | Wert | Beschreibung |
|---|---|---|
QLockFile::NoError | 0 | Die Sperre wurde erfolgreich erworben. |
QLockFile::LockFailedError | 1 | Die Sperre konnte nicht erworben werden, da sie von einem anderen Prozess gehalten wird. |
QLockFile::PermissionError | 2 | Die Sperrdatei konnte nicht erstellt werden, da im übergeordneten Verzeichnis keine Berechtigungen vorhanden waren. |
QLockFile::UnknownError | 3 | Es ist ein anderer Fehler aufgetreten, beispielsweise hat eine volle Partition das Schreiben der Sperrdatei verhindert. |
Dokumentation der Member-Funktionen
[explicit] QLockFile::QLockFile(const QString &fileName)
Erstellt ein neues Sperrdateiobjekt. Das Objekt wird im entsperrten Zustand erstellt. Beim Aufruf von ` lock()` oder ` tryLock()` wird eine Sperrdatei namens ` fileName ` erstellt, sofern diese noch nicht existiert.
Siehe auch lock() und unlock().
[noexcept] QLockFile::~QLockFile()
Löscht das Sperrdateiobjekt. Wenn die Sperre erworben wurde, wird sie dadurch freigegeben, dass die Sperrdatei gelöscht wird.
QLockFile::LockError QLockFile::error() const
Gibt den Fehlerstatus der Sperrdatei zurück.
Wenn ` tryLock()` den Wert ` false` zurückgibt, kann diese Funktion aufgerufen werden, um den Grund für das Scheitern der Sperrung zu ermitteln.
QString QLockFile::fileName() const
Gibt den Dateinamen der Sperrdatei zurück
bool QLockFile::getLockInfo(qint64 *pid, QString *hostname, QString *appname) const
Ruft Informationen über den aktuellen Eigentümer der Sperrdatei ab.
Wenn ` tryLock()` den Wert ` false` und ` error()` den Wert ` LockFailedError` zurückgibt, kann diese Funktion aufgerufen werden, um weitere Informationen über die vorhandene Sperrdatei zu erhalten:
- die PID der Anwendung (zurückgegeben von ` pid`)
- den hostname, auf dem sie läuft (nützlich bei vernetzten Dateisystemen),
- den Namen der Anwendung, die sie erstellt hat (wird in ` appname` zurückgegeben),
Beachten Sie, dass ` tryLock()` die Datei automatisch löscht, wenn keine Anwendung mit dieser PID läuft; daher kann ` LockFailedError ` nur aufgerufen werden, wenn eine Anwendung mit dieser PID vorhanden ist (die jedoch möglicherweise in keinem Zusammenhang steht).
Dies kann genutzt werden, um Benutzer über die vorhandene Sperrdatei zu informieren und ihnen die Möglichkeit zu geben, diese zu löschen. Nach dem Entfernen der Datei mit ` removeStaleLockFile()` kann die Anwendung ` tryLock()` erneut aufrufen.
Diese Funktion gibt ` true ` zurück, wenn die Informationen erfolgreich abgerufen werden konnten, und `false`, wenn die Sperrdatei nicht existiert oder nicht die erwarteten Daten enthält. Dies kann passieren, wenn die Sperrdatei zwischen dem Zeitpunkt, zu dem ` tryLock()` fehlgeschlagen ist, und dem Aufruf dieser Funktion gelöscht wurde. Rufen Sie in diesem Fall einfach erneut ` tryLock()` auf.
bool QLockFile::isLocked() const
Gibt „ true “ zurück, wenn die Sperre von dieser „ QLockFile “-Instanz erworben wurde, andernfalls „ false “.
Siehe auch lock(), unlock() und tryLock().
bool QLockFile::lock()
Erstellt die Sperrdatei.
Wenn ein anderer Prozess (oder ein anderer Thread) die Sperrdatei bereits erstellt hat, blockiert diese Funktion so lange, bis dieser Prozess (oder Thread) sie freigibt.
Es ist nicht zulässig, diese Funktion mehrmals für dieselbe Sperre aus demselben Thread aufzurufen, ohne zuvor die Sperre aufzuheben. Diese Funktion führt zu einem Deadlock, wenn die Datei rekursiv gesperrt wird.
Gibt ` true ` zurück, wenn die Sperre erworben wurde, und `false`, wenn sie aufgrund eines nicht behebbaren Fehlers – beispielsweise fehlender Berechtigungen im übergeordneten Verzeichnis – nicht erworben werden konnte.
Siehe auch ` unlock()` und ` tryLock()`.
bool QLockFile::removeStaleLockFile()
Versuche, eine vorhandene Sperrdatei zwangsweise zu entfernen.
Der Aufruf dieser Funktion wird beim Schutz einer kurzlebigen Operation nicht empfohlen: „ QLockFile “ sorgt bereits dafür, dass Sperrdateien entfernt werden, sobald sie älter sind als „ staleLockTime “ ().
Diese Methode sollte nur aufgerufen werden, wenn eine Ressource über einen längeren Zeitraum geschützt wird, d. h. mit ` staleLockTime(0)`, und nachdem ` tryLock()` den Wert ` LockFailedError` zurückgegeben hat und der Benutzer dem Entfernen der Sperrdatei zugestimmt hat.
Gibt bei Erfolg „ true “ zurück, andernfalls „false“, wenn die Sperrdatei nicht entfernt werden konnte. Dies tritt unter Windows auf, wenn die Anwendung, die die Sperre besitzt, noch ausgeführt wird.
void QLockFile::setStaleLockTime(int staleLockTime)
Legt „ staleLockTime “ auf die Zeit in Millisekunden fest, nach deren Ablauf eine Sperrdatei als veraltet gilt. Der Standardwert beträgt 30000, d. h. 30 Sekunden. Wenn Ihre Anwendung die Datei in der Regel länger als 30 Sekunden gesperrt hält (beispielsweise beim Speichern von Megabyte an Daten über einen Zeitraum von 2 Minuten), sollten Sie mit `setStaleLockTime()` einen höheren Wert festlegen.
Der Wert von ` staleLockTime ` wird von ` lock()` und ` tryLock()` verwendet, um zu bestimmen, wann eine vorhandene Sperrdatei als veraltet gilt, d. h. als Überbleibsel eines abgestürzten Prozesses. Dies ist nützlich für den Fall, dass die PID inzwischen wiederverwendet wurde; eine Möglichkeit, eine veraltete Sperrdatei zu erkennen, besteht daher darin, dass sie bereits seit längerer Zeit vorhanden ist.
Dies ist eine überladene Funktion, die dem Aufruf von
setStaleLockTime(std::chrono::milliseconds{staleLockTime});Siehe auch staleLockTime().
[since 6.2] void QLockFile::setStaleLockTime(std::chrono::milliseconds staleLockTime)
Legt das Intervall fest, nach dessen Ablauf eine Sperrdatei als veraltet gilt ( staleLockTime). Der Standardwert beträgt 30 Sekunden.
Wenn Ihre Anwendung die Datei in der Regel länger als 30 Sekunden gesperrt hält (beispielsweise beim Speichern von Megabytes an Daten über einen Zeitraum von 2 Minuten), sollten Sie mit `setStaleLockTime()` einen größeren Wert festlegen.
Der Wert von ` staleLockTime()` wird von ` lock()` und ` tryLock()` verwendet, um zu bestimmen, wann eine vorhandene Sperrdatei als veraltet gilt, d. h. als Überbleibsel eines abgestürzten Prozesses. Dies ist nützlich für den Fall, dass die PID inzwischen wiederverwendet wurde; eine Möglichkeit, eine veraltete Sperrdatei zu erkennen, besteht daher darin, dass sie bereits seit langer Zeit vorhanden ist.
Wird dieser Wert auf 0 oder einen negativen Wert gesetzt, wird die Überprüfung der Zeitstempel von Sperrdateien deaktiviert. ` QLockFile ` erkennt dennoch eine veraltete Sperrdatei, wenn deren Inhalt zeigt, dass der sperrende Prozess nicht mehr läuft.
Diese Funktion wurde in Qt 6.2 eingeführt.
Siehe auch staleLockTime().
int QLockFile::staleLockTime() const
Gibt die Zeit in Millisekunden zurück, nach deren Ablauf eine Sperrdatei als veraltet gilt.
Siehe auch ` setStaleLockTime()`.
[since 6.2] std::chrono::milliseconds QLockFile::staleLockTimeAsDuration() const
Gibt ein std::chrono::milliseconds-Objekt zurück, das die Zeit angibt, nach deren Ablauf eine Sperrdatei als veraltet gilt.
Diese Funktion wurde in Qt 6.2 eingeführt.
Siehe auch ` setStaleLockTime()`.
bool QLockFile::tryLock(int timeout)
Versucht, die Sperrdatei zu erstellen. Diese Funktion gibt ` true ` zurück, wenn die Sperre erworben wurde; andernfalls gibt sie ` false` zurück. Wenn ein anderer Prozess (oder ein anderer Thread) die Sperrdatei bereits erstellt hat, wartet diese Funktion höchstens ` timeout ` Millisekunden, bis die Sperrdatei verfügbar wird.
Hinweis: Die Übergabe einer negativen Zahl als „ timeout “ entspricht dem Aufruf von „ lock()“, d. h., diese Funktion wartet unendlich lange, bis die Sperrdatei gesperrt werden kann, wenn „ timeout “ negativ ist.
Wurde die Sperre erworben, muss sie mit ` unlock()` freigegeben werden, bevor ein anderer Prozess (oder Thread) sie erfolgreich sperren kann.
Der mehrfache Aufruf dieser Funktion für dieselbe Sperre aus demselben Thread heraus, ohne diese zuvor freizugeben, ist nicht zulässig; diese Funktion gibt beim Versuch, die Datei rekursiv zu sperren, stets „false“ zurück.
Siehe auch lock() und unlock().
[since 6.2] bool QLockFile::tryLock(std::chrono::milliseconds timeout = std::chrono::milliseconds::zero())
Versucht, die Sperrdatei zu erstellen. Diese Funktion gibt ` true ` zurück, wenn die Sperre erworben wurde; andernfalls gibt sie ` false` zurück. Wenn ein anderer Prozess (oder ein anderer Thread) die Sperrdatei bereits erstellt hat, wartet diese Funktion höchstens ` timeout `, bis die Sperrdatei verfügbar wird.
Wurde die Sperre erhalten, muss sie mit ` unlock()` freigegeben werden, bevor ein anderer Prozess (oder Thread) sie erfolgreich sperren kann.
Es ist nicht zulässig, diese Funktion mehrmals vom selben Thread aus für dieselbe Sperre aufzurufen, ohne sie zuvor freizugeben; diese Funktion gibt immer „false“ zurück, wenn versucht wird, die Datei rekursiv zu sperren.
Dies ist eine überladene Funktion.
Diese Funktion wurde in Qt 6.2 eingeführt.
Siehe auch ` lock()` und ` unlock()`.
void QLockFile::unlock()
Hebt die Sperre auf, indem die Sperrdatei gelöscht wird.
Der Aufruf von `unlock()` ohne vorherige Sperrung der Datei hat keine Auswirkung.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.