Stefan Muenz: mehrere Benutzer - eine Datei - was kann passieren ?

Beitrag lesen

Hallo Norbert,

Ich habe vor wenigen Tagen dieses Forum durchblättert und dabei über das Problem von möglichem Datenverlust bei mehreren gleichzeitigen Zugriffen auf eine Datei gelesen. Bis zu diesem Zeitpunkt habe ich mir eigentlich auch noch keine Gedanken darüber gemacht und eigentlich vermutet, dass das Betriebssystem dies koordiniert - aber nun möchte ich doch vorbeugend Infos einholen.

Es gibt in Perl die Funktion flock(), die da gute Dienste leisten kann. Die Funktion regelt, wie andere Prozesse auf eine Datei zugreifen koennen, waehrend das aktuelle Script die Datei geoeffnet hat. Bei Betriebssystemen allerdings, die keinen Zugriffsschutz für geoeffnete Dateien implementiert haben, fuehrt die Anwendung dieser Funktion zu einem Fehler, so etwa auch bei Windows 95/98.

Erwartet als Parameter:
1. das Handle des Ein-/Ausgabekanals der geöffneten Datei.
2. die Nummer einer Lock-Operation - erlaubt sind die Nummern 1, 2, 4 und 8:
Nummer 1 bedeutet shared (Datei ausdruecklich mit anderen Prozessen teilen),
Nummer 2 bedeutet exclusive (Normalfall - keinem anderen Prozess irgendeinen Zugriff auf die Datei erlauben),
Nummer 4 bedeutet non-blocking (Datei nicht voellig blockieren - zum Beispiel lesenden Zugriff anderer Prozesse zulassen),
Nummer 8 bedeutet unlock (Zugriffsschutz ausdruecklich wieder aufheben).

und mal ein Beispiel - keine Ahnung, ob das so korrekt angewendet ist

#!/usr/bin/perl

open(LOGFILE, "</web/logs/access.log");
flock(LOGFILE, 1);

sub Lesen {
seek(LOGFILE,0,0);
@Zeilen = <LOGFILE>
$Anzahl = 0;
foreach(@Zeilen) { $Anzahl++; }
}

print "Content-type: text/html\n\n";
print "<html><head><title>Testausgabe</title>\n";
print "</head><body>\n";
&Lesen;
print "<p>Die Logdatei hat im Augenblick $Anzahl Zeilen</p>\n";

angenommen, hier passiert etwas Zeitaufwendiges,

und derweil greift ein anderer Prozess auf test.txt zu

&Lesen;
print "<p>Die Logdatei hat jetzt $Anzahl Zeilen</p>\n";
print "</body></html>\n";

flock(LOGFILE, 8);
close(LOGFILE);

viele Gruesse
  Stefan Muenz