flock gegen lockf unter Linux

Lesezeit: 4 Minuten

Wenn lockf wird mit einem Offset von 0 verwendet, was sind die Unterschiede zwischen flock und lockf bei Verwendung im exklusiven Modus, falls vorhanden?

Ich frage, weil ich Code lese, der bedingt in einer dieser beiden Funktionen basierend auf der Plattform kompiliert wird, und ich mögliche Gründe dafür verstehen möchte.

Benutzeravatar von Nominal Animal
Nominelles Tier

Der praktische Unterschied zw flock() und lockf() liegt in der Semantik (Verhalten in Bezug auf Schließen und Weitergeben), Anwendbarkeit über NFS und andere gemeinsam genutzte Dateisysteme und ob die beratenden Sperren für andere Prozesse sichtbar sind, die verwenden fcntl() Sperren oder nicht.

Die von Ihnen verwendete Bibliothek verfügt einfach über eine Logik, um die gewünschte Semantik basierend auf der aktuellen Plattform auszuwählen.

Wenn die Semantik (Verhalten gegenüber Deskriptorübergabe, Verzweigung usw.) akzeptabel ist, sollten Sie dies vorziehen lockf()/fcntl() sperrt über flock() Sperren in Linux, einfach weil ersteres auf NFS-Dateisystemen usw. funktioniert, während letzteres dies nicht tut. (Auf BSDs und Mac OS X glaube ich, dass Sie explizit verwenden müssen fcntl()stattdessen.)


Unter Linux, lockf() ist nur ein Wrapper herum fcntl()während flock() Sperren sind separat (und funktionieren nur auf lokalen Dateisystemen, nicht zB auf NFS-Mounts auf Kerneln vor 2.6.12). Das heißt, ein Prozess kann eine exklusive Beratung haben flock() eine Datei sperren, während ein anderer Prozess eine exklusive Empfehlung hat fcntl() sperren Sie dieselbe Datei. Beides sind beratende Sperren, aber sie interagieren nicht.

An Mac OS X und FreeBSD, lockf()/flock()/fcntl() Sperren interagieren alle, obwohl Entwicklern empfohlen wird, nur eine der Schnittstellen in einer Anwendung zu verwenden. Allerdings nur fcntl() Schlösser funktionieren NFS-Mounts (und natürlich nur, wenn sowohl der NFS-Client als auch der Server so konfiguriert wurden, dass sie Datensatzsperren unterstützen, was überraschend selten in zB Webhosting-Umgebungen vorkommt; eine große Ursache für Kopfschmerzen für einige Web(Framework)-Entwickler).

POSIX gibt nicht explizit an, wie lockf()/flock()/fcntl() Schlösser sollten interagieren, und in der Vergangenheit gab es Unterschiede. Jetzt hat sich die Lage etwas beruhigt, und man kann etwa Sag das

  1. fcntl() Schlösser sind die zuverlässigsten

    Über alle Architekturen hinweg haben sie die besten Chancen, direkt an beispielsweise gemeinsam genutzten Dateisystemen zu arbeiten – beispielsweise NFS- und CIFS-Mounts.

  2. Meistens, lockf() wird als “Kurzschrift” für implementiert fcntl()

    Die andere Alternative, als “Kurzschrift” für flock()ist möglich, aber heutzutage selten.

  3. fcntl() und flock() haben unterschiedliche Semantik bzgl. Vererbung und automatische Freigaben

    fcntl() Sperren bleiben über ein erhalten exec()aber nicht über a vererbt fork(). Die Sperren werden freigegeben, wenn der besitzende Prozess schließt irgendein Deskriptor, der auf dieselbe Datei verweist.

    Unter Linux, FreeBSD und MAC OS X flock() Sperren sind mit dem offenen Dateideskriptor gekoppelt: Durch das Übergeben des Deskriptors wird auch die Sperre übergeben. (Die Manpages sagen das “Die Sperre liegt auf der Datei, nicht auf dem Dateideskriptor”. Dies ist kein Widerspruch. Es bedeutet nur, dass das Schloss gilt zur Datei. Es ist immer noch so an den Deskriptor gekoppelt, dass beim Duplizieren des Deskriptors auch dieselbe Sperre übergeben wird.) Daher ist es möglich, dass mehrere Prozesse denselben exklusiven Hinweis haben flock() gleichzeitig auf dieselbe Datei sperren, wenn sie den Deskriptor vom Urheber nach der erhalten haben flock() Anruf.

Das Sperren von Dateien ist ein überraschend kompliziertes Problem. Ich persönlich habe die besten Ergebnisse erzielt, indem ich mich einfach daran gehalten habe fcntl() Verriegelung. Die Semantik bzgl. fcntl() Sperren sind nicht einfach zu handhaben und können in bestimmten Fällen ehrlich gesagt ärgerlich sein; Es ist nur so, dass ich festgestellt habe, dass es die besten – zuverlässigsten, portabelsten, am wenigsten überraschenden – Ergebnisse liefert.

  • Nachtrag zum obigen Kommentar: Linux 2.6.12 wurde am 18. Juni 2005 veröffentlicht, also funktionierte flock() sogar zum Zeitpunkt der Antwort auf NFS.

    – Akilan

    16. Mai 2018 um 11:24 Uhr

  • @Akilan: Welcher Teil? Nicht verwechseln flock() mit lockf(); Es ist schrecklich, so etwas zu kommentieren, ohne genau darauf hinzuweisen, was falsch ist. Es ist, als würde man sagen, dass man einen Fehler gemacht hat, ohne auf den Fehler hinzuweisen. Das ist nicht nur wenig hilfreich, sondern macht den Ton auch sehr selbstgefällig und unfreundlich. Ich glaube, Sie haben sich gerade verwirrt lockf() und flock() im Abschnitt ANMERKUNGEN. Was NFS und flock() auf Kerneln vor 2.6.12, ja, das rechtfertigt eine Anmerkung, danke.

    – Nominelles Tier

    16. Mai 2018 um 12:50 Uhr


  • Es tut mir leid, dass es nicht ganz klar war. Ich rede tatsächlich vom NFS.

    – Akilan

    17. Mai 2018 um 12:18 Uhr

  • @Akilan: Nein, das war klar. Sie sagten, “die Antwort ist nicht mehr wahr”, haben aber nicht darauf hingewiesen wie, oder welcher Teil. Ohne weitere Details muss ich widersprechen, denn außer der Erwähnung der Kernel-Version sehe ich überhaupt nicht, wie sich meine Antwort von der Manpage unterscheidet.

    – Nominelles Tier

    17. Mai 2018 um 12:34 Uhr

Der wahrscheinlichste Grund für die bedingte Kompilierung ist, dass keine der beiden Funktionen auf jeder Plattform verfügbar ist.

  • Das war mein erster Gedanke, die Überprüfung ergab, dass beide auf den Plattformen unterstützt wurden. Historisch gesehen war dies möglicherweise nicht der Fall, daher scheint dies der Spitzenreiter zu sein.

    – Dan McGrath

    14. März 2014 um 15:55 Uhr

1387190cookie-checkflock gegen lockf unter Linux

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

Privacy policy