fcntl, lockf, was ist besser zum Sperren von Dateien geeignet?

Lesezeit: 7 Minuten

Suche nach Informationen bzgl Vorteile und Nachteile von beiden fktl und lockf zum Sperren von Dateien. Was ist zum Beispiel besser für die Portabilität zu verwenden? Ich codiere gerade einen Linux-Daemon und frage mich, welcher besser geeignet ist, um den gegenseitigen Ausschluss zu erzwingen.

Benutzeravatar von Brian R. Bondy
Brian R. Bondy

Was ist der Unterschied zwischen lockf und fcntl:

Auf vielen Systemen ist die lockf() Die Bibliotheksroutine ist nur ein Wrapper fcntl(). Das heißt lockf bietet eine Teilmenge der Funktionalität, die fcntl tut.

Quelle

Aber auf manchen Systemen fcntl und lockf Schlösser sind völlig unabhängig.

Quelle

Da dies implementierungsabhängig ist, stellen Sie sicher, dass Sie immer dieselbe Konvention verwenden. Verwenden Sie also entweder immer lockf von beiden Prozessen oder verwenden Sie immer fcntl. Es besteht eine gute Chance, dass sie austauschbar sind, aber es ist sicherer, dasselbe zu verwenden.

Welche Sie gewählt haben, spielt keine Rolle.


Einige Hinweise zu obligatorischen vs. beratenden Sperren:

Sperren in Unix/Linux ist standardmäßig beratend, was bedeutet, dass andere Prozesse die festgelegten Sperrregeln nicht befolgen müssen. Es spielt also keine Rolle, wie Sie abschließen, solange Ihre kooperierenden Prozesse ebenfalls dieselbe Konvention verwenden.

Linux unterstützt obligatorisch Sperren, aber nur, wenn Ihr Dateisystem mit der Option on gemountet ist und die speziellen Dateiattribute gesetzt sind. Sie können verwenden mount -o mand um das Dateisystem zu mounten und die Dateiattribute festzulegen g-x,g+s um obligatorische Sperren zu aktivieren, verwenden Sie dann fcntl oder lockf. Weitere Informationen zur Funktionsweise obligatorischer Sperren finden Sie unter hier.

Beachten Sie, dass Sperren nicht auf die einzelne Datei, sondern auf den Inode angewendet werden. Das bedeutet, dass zwei Dateinamen, die auf dieselben Dateidaten verweisen, denselben Sperrstatus haben.

In Windows hingegen können Sie eine Datei aktiv exklusiv öffnen, wodurch andere Prozesse daran gehindert werden, sie vollständig zu öffnen. Auch wenn sie es wollen. Dh die Sperren sind obligatorisch. Dasselbe gilt für Windows- und Dateisperren. Jeder Prozess mit einem geöffneten Dateihandle mit entsprechendem Zugriff kann einen Teil der Datei sperren, und kein anderer Prozess kann auf diesen Teil zugreifen.


So funktionieren obligatorische Sperren unter Linux:

In Bezug auf obligatorische Sperren gilt: Wenn ein Prozess einen Bereich einer Datei mit einer Lesesperre sperrt, dürfen andere Prozesse in diesem Bereich lesen, aber nicht schreiben. Wenn ein Prozess einen Bereich einer Datei mit einer Schreibsperre sperrt, dann dürfen andere Prozesse weder lesen noch in die Datei schreiben. Was passiert, wenn ein Prozess nicht auf den Teil der Datei zugreifen darf, hängt davon ab, ob Sie angegeben haben O_NONBLOCK oder nicht. Wenn die Blockierung eingestellt ist, wartet es auf die Ausführung der Operation. Wenn keine Blockierung eingestellt ist, erhalten Sie einen Fehlercode von EAGAIN.


NFS-Warnung:

Seien Sie vorsichtig, wenn Sie Sperrbefehle auf einem NFS-Mount verwenden. Das Verhalten ist undefiniert und die Implementierung variiert stark, ob nur eine lokale Sperre verwendet wird oder eine Remote-Sperre unterstützt wird.

  • Das ist nicht mehr richtig. Das Sperren von Dateien funktioniert auf nfs 3.0, aber nur mit fcntl, nicht mit flock

    – frankc

    2. Juli 2010 um 16:23 Uhr

  • “Aber auf einigen Systemen sind fcntl- und lockf-Sperren völlig unabhängig” — Nein. Auf einigen Systemen sind fcntl- und flock-Sperren völlig unabhängig, wie in dem von Ihnen verlinkten Artikel erläutert. fcntl- und lockf-Sperren stehen jedoch immer in Beziehung (nur nicht in Beziehung zu flock).

    – Windows-Programmierer

    20. Januar 2011 um 1:57 Uhr

Beide Schnittstellen sind Teil des POSIX-Standards, und heutzutage sind beide Schnittstellen auf den meisten Systemen verfügbar (ich habe gerade Linux, FreeBSD, Mac OS X und Solaris überprüft). Wählen Sie daher dasjenige aus, das Ihren Anforderungen besser entspricht, und verwenden Sie es.

Ein Wort der Vorsicht: Es ist nicht spezifiziert, was passiert, wenn ein Prozess eine Datei mit fcntl und ein anderer mit lockf sperrt. In den meisten Systemen sind dies äquivalente Operationen (tatsächlich wird unter Linux lockf auf fcntl implementiert), aber POSIX sagt, dass ihre Interaktion nicht spezifiziert ist. Wenn Sie also mit einem anderen Prozess zusammenarbeiten, der eine der beiden Schnittstellen verwendet, wählen Sie dieselbe.

Andere haben geschrieben, dass die Sperren nur beratend sind: Sie sind dafür verantwortlich zu prüfen, ob eine Region gesperrt ist. Verwenden Sie auch keine stdio-Funktionen, wenn Sie die Sperrfunktion verwenden möchten.

vladrs Benutzeravatar
vladr

Ihre Hauptanliegen in diesem Fall (dh wenn “Programmieren eines Linux-Daemons und fragen sich, was besser geeignet ist, zu verwenden zur Durchsetzung des gegenseitigen Ausschlusses“), sollte sein:

  1. Wird die gesperrte Datei lokal sein oder kann sie sich auf NFS befinden?
    • Kann der Benutzer Sie beispielsweise dazu verleiten, die PID-Datei Ihres Daemons auf NFS zu erstellen und zu sperren?
  2. wie verhält sich das Schloss wann forking, oder wenn der Daemon-Prozess mit extremen Vorurteilen beendet wird, z kill -9?

Das flock und fcntl Befehle verhalten sich in beiden Fällen unterschiedlich.

Meine Empfehlung wäre zu verwenden fcntl. Sie können sich auf die beziehen Artikel zum Sperren von Dateien auf Wikipedia für eine eingehende Diskussion der Probleme, die mit beiden Lösungen verbunden sind:

Sowohl flock als auch fcntl haben Macken, die Programmierer anderer Betriebssysteme gelegentlich verwirren. Ob Flocklocks auf Netzwerkdateisystemen wie NFS funktionieren, hängt von der Implementierung ab. Auf BSD-Systemen sind Herdenaufrufe erfolgreiche No-Ops. Unter Linux vor 2.6.12 wirkten Flock-Aufrufe auf NFS-Dateien nur lokal. Kernel 2.6.12 und höher implementieren Flock-Aufrufe für NFS-Dateien unter Verwendung von POSIX-Bytebereichssperren. Diese Sperren sind für andere NFS-Clients sichtbar, die fcntl()/POSIX-Sperren implementieren.1 Sperr-Upgrades und -Downgrades heben die alte Sperre auf, bevor die neue Sperre angewendet wird. Wenn eine Anwendung eine exklusive Sperre auf eine gemeinsame Sperre herunterstuft, während eine andere Anwendung blockiert ist und auf eine exklusive Sperre wartet, erhält die letztere Anwendung die exklusive Sperre und die erste Anwendung wird gesperrt. Alle fcntl-Sperren, die einer Datei für einen bestimmten Prozess zugeordnet sind, werden entfernt, wenn ein Dateideskriptor für diese Datei von diesem Prozess geschlossen wird, selbst wenn für diesen Dateideskriptor nie eine Sperre angefordert wurde. Außerdem werden fcntl-Sperren nicht von einem untergeordneten Prozess geerbt. Die fcntl close-Semantik ist besonders problematisch für Anwendungen, die Subroutinenbibliotheken aufrufen, die auf Dateien zugreifen können.

Ich bin kürzlich bei der Verwendung von fcntl und flock auf ein Problem gestoßen, von dem ich dachte, dass ich es hier melden sollte, da die Suche nach einem der beiden Begriffe diese Seite bei beiden ganz oben anzeigt.

Zu beachten sind BSD-Sperren, wie oben erwähnt beratend. Für diejenigen, die nicht wissen, dass OSX (Darwin) BSD ist. Dies muss beachtet werden, wenn eine Datei zum Schreiben geöffnet wird.

Um fcntl/flock zu verwenden, müssen Sie zuerst die Datei öffnen und ihre ID abrufen. Wenn Sie die Datei jedoch mit “w” geöffnet haben, wird die Datei sofort angezeigt auf Null gesetzt. Wenn Ihr Prozess die Sperre dann nicht erhält, da die Datei an anderer Stelle verwendet wird, wird er höchstwahrscheinlich zurückkehren und die Datei als 0 KB belassen. Der Prozess, der die Sperre hatte, stellt nun fest, dass die Datei darunter verschwunden ist, was normalerweise zu katastrophalen Folgen führt.

Um diese Situation zu beheben, wenn Sie Dateisperren verwenden, noch nie Öffnen Sie die Datei “w”, öffnen Sie sie stattdessen “a”, um sie anzuhängen. Wenn die Sperre erfolgreich erworben wurde, können Sie die Datei dann sicher löschen, wie es “w” getan hätte, dh. :

fseek(fileHandle, 0, SEEK_SET);//zum Anfang bewegen

ftruncate(fileno((FILE *) fileHandle), 0);//Löschen

Das war eine unangenehme Lektion für mich.

Da Sie nur einen Daemon codieren, der ihn zum gegenseitigen Ausschluss verwendet, sind sie gleichwertig, schließlich muss Ihre Anwendung nur mit sich selbst kompatibel sein.

Der Trick bei den Dateisperrmechanismen besteht darin, konsistent zu sein – verwenden Sie einen und bleiben Sie dabei. Sie zu variieren ist eine schlechte Idee.

Ich gehe hier davon aus, dass es sich bei dem Dateisystem um ein lokales Dateisystem handelt. Wenn dies nicht der Fall ist, sind alle Wetten abgeschlossen. NFS / andere Netzwerkdateisysteme behandeln das Sperren mit unterschiedlicher Effektivität (in einigen Fällen keine).

1408970cookie-checkfcntl, lockf, was ist besser zum Sperren von Dateien geeignet?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy