Teil von SELFHTML aktuell Teil von Artikel Teil von Programmiertechnik Teil von Sperren von Dateien

Sperren von Dateien: Typische Fehler beim Sperren von Dateien

nach unten Allgemeines
nach unten Dateien zum Schreiben öffnen
nach unten Zusammenhängende Operationen trennen
nach unten Dateien vor dem Schließen entsperren

Allgemeines

Es gibt einige typische Fehler beim Sperren von Dateien, die immer wieder gemacht werden. Dieser Abschnitt erläutert diese Fehler und erklärt die Hintergründe. In den nächsten Abschnitten wird dann gezeigt, wie das Sperren von Dateien richtig funktioniert.

nach obennach unten

Datei zum Schreiben öffnen

Wird eine Datei zum Schreiben geöffnet, so wird der Dateiinhalt in diesem Moment automatisch gelöscht! Jeder Aufruf einer Funktion, die die Datei sperren soll, kommt zu spät für eventuell parallel lesende Zugriffe. Daher ist es essentiell, dass eine Datei nicht zum Schreiben geöffnet wird. In folgender Tabelle sind Codeausschnitte, wie sie typischerweise in Programmiersprachen verwendet werden, um Dateien zum Schreiben zu öffnen. Diese Codeausschnitte sollten nicht verwendet werden, sie sind als Negativbeispiele aufgeführt!

Sprache Code (Negativbeispiel!)
PHP $fp = fopen ('datei', 'w');
flock ($fp, LOCK_EX);
Perl open FP, ">", "datei";
flock FP, LOCK_EX;
Python fp = open ('datei', 'w')
fcntl.flock (fp.fileno (), fcntl.LOCK_EX)
Java stream = new FileOutputStream ("datei");
myLock = stream.getChannel ().lock ();

Welche Abhilfe gibt es? Die einfachste Möglichkeit ist, die Datei zum Lesen und Schreiben zu öffnen (hauptsächlich jedoch zum Lesen, Dateimodi wie w+ in PHP/Python oder >+ in Perl sind auch nicht sinnvoll!) und dann nach Erhalt der Dateisperre den Dateiinhalt zu löschen. Weiter unten im Artikel werden die korrekten Lösungen für die hier beschriebenen Programmiersprachen angeführt und erläutert.

nach obennach unten

Zusammenhängende Operationen trennen

Erinnert man sich an den Zähler, der in der Einführung des Artikels vorgestellt wurde, gibt es auch hier Fälle, in denen selbst bei Benutzung von Dateisperren es zu inkorrekten Ergebnissen kommen kann - wenngleich die Information in der Datei selbst nicht verloren gehen kann. Der Zähler sei im folgenden Szenario nicht wie oben implementiert, sondern in zwei Teile geteilt:

  1. Öffne die Datei, sperre sie mitbenutzbar, lese den Inhalt aus, hebe die Sperre auf, schließe sie.
  2. Öffne die Datei, sperre sie exklusiv, schreibe den neuen Inhalt hinein, hebe die Sperre auf, schließe sie.

Sofern das Öffnen und Sperren korrekt implementiert ist, sieht dies erst einmal formal korrekt aus. Es gibt jedoch auch hier eine race condition:

  1. Script 1 führt den ersten Schritt durch und erhält den aktuellen Zählerstand, z.B. 42.
  2. Script 2 führt den ersten Schritt durch und erhält den gleichen Zählerstand wie Script 1, also auch 42.
  3. Script 1 führt den zweiten Schritt durch und schreibt 43 in die Datei.
  4. Script 2 führt den zweiten Schritt durch und schreibt 43 in die Datei.

Wie man hier erkennen kann, ist ein Aufruf zu wenig gezählt worden, tatsächlich hätte 44 in die Datei geschrieben werden sollen. Das ist hier im Falle des Zählers nicht gravierend, bei anspruchsvolleren Programmen kann dieses Verhalten jedoch durchaus ernste Probleme verursachen.

Der Ausweg hierzu: Wenn ein Programm oder Script auf den Inhalt der Datei direkt sofort reagieren muss, dann muss es die Datei bereits vor dem Lesen exklusiv sperren, die Sperre aufrecht erhalten, solange der Inhalt verarbeitet wird, den Dateiinhalt danach löschen und den neuen Inhalt in die Datei schreiben, und danach erst die Dateisperre aufheben. Denn nur so ist sichergestellt, dass der Zugriff auf die Datei vollkommen isoliert war. Auch hier wird der entsprechend korrekte Code weiter unten vorgestellt.

nach obennach unten

Dateien vor dem Schließen entsperren

Oftmals wird vor dem Schließen der Dateien die Dateisperre aufgehoben. Dies kann problematisch sein, denn meistens wird gepufferte Ein- und Ausgabe verwendet, d.h. die Ausgabe in eine Datei wird im Speicher vorgehalten, um sie später - spätestens beim Schließen der Datei - tatsächlich schreiben zu können. Falls nun jedoch ein Schreibbefehl gepuffert (d.h. effektiv noch nicht ausgeführt wird), dann die Sperre entfernt und danach erst die Datei geschlossen wird, führt dies dazu, dass der Schreibbefehl erst beim Schließen der Datei ausgeführt wird, wenn die Sperre schon längst entfernt wurde. Da Sperren beim Schließen der Datei automatisch entfernt werden, ist es sinnvoller, die Datei einfach nur zu schließen, ohne sich um die Sperre explizit zu kümmern.

Nur wer explizit die Datei offen halten will, sollte Sperren manuell entfernen - dafür aber vorher mit geeigneten Funktionen sicherstellen, dass alle Puffer geleert sind, d.h. dass alle Schreiboperationen auf die Datei erfolgt sind.

weiter Seite Dateien mit PHP sperren

zurück Seite Dateisperren in verschiedenen Betriebssystemen

Teil von SELFHTML aktuell Teil von Artikel Teil von Programmiertechnik Teil von Sperren von Dateien

© 2006 bereichsübergreifende Seite Impressum