Hallo auch!
Oh, ein leidiges Thema... Also, folgendes Verfahren ist ausgetestet und relativ sicher, aber eben auch nicht absolut:
1.) Vor dem Lesen der Datei $filename prüfst Du
while (-e "$filename.flock" && $flockcount < 5000) { $flockcount++; }
2.) Vor dem Schreiben der Datei $filename erstellst Du $filename.flock mit einem Dummy-Wert:
open(FLOCK,"$filename.flock");
print FLOCK "1";
close(FLOCK);
3.) Nach dem Schließen der Datei $filename führst Du system("rm $filename.flock") aus.Wie gesagt funktioniert das ganze recht gut bei mir, und zwar bei ziemlich starken Einsatz (durchschnittlich(!) alle 30 Sekunden für die selbe Datei). Wenn Du alle Dateizugriffe mit diesem System versiehst, sollte Deine Zählerdatei also sicher sein. Zusätzlich kannst Du aber noch beispielsweise ein mal täglich ein Backup der Datei machen.
Die von mir verwendete Variante schaut doch ziemlich ähnlich aus - aber nur fast. Bei meinen Überlegungen kam mal so die Frage auf, was denn nun passiert, wenn zwei Prozesse gleichzeitig sehen, daß die *.flock Datei NICHT existier. In diesem Falle würden beide gleichzeitig davon ausgehen, die gesperrte Datei nutzen zu können ...
Wie aber kann ich sicherstellen, daß nur ein Prozess zur Zeit eine flock-Datei anlegt??? Oder allgemeiner gesagt - nur ein Prozess soll den Status auf locked ändern können.
Meine Idee war nun, daß das löschen einer Datei nur einmal (korrekt) auftreten kann. Die Perl-eigene Funktion zum löschen von Dateien (unlink) gibt glücklicherweise zurück, wieviele der angegebenen Dateien gelöscht wurden! Die geänderte Variante würde also ungefähr wie folgt ausschauen:
1.) Vor dem Lesen der Datei $filename prüfst Du
while (!-e "$filename.noflock" && $flockcount < 5000) { $flockcount++; }
2.) Vor dem Schreiben der Datei $filename löscht Du $filename.noflock
if (unlock("$filename.noflock"))
{
[...]
}
3.) Nach dem Schließen der Datei $filename führst Du system("touch $filename.noflock") aus.
So ähnlich jedenfalls. Man sollte hier natürloch noch den Fall abfangen, daß die Datei nicht gelöscht werden konnte. In diesem Falle könnte man z.B. einfach wieder von vorne anfangen.
Zum Schluß noch eine Anmerkung: Das warten, welches Cheatah hier einsetzt ist ziemlich aktiv (busy waiting). hier sollte man wohl ein sleep mit in die Schleife setzen, so daß man das Heft regelmäßig an das Betriebssystem abgibt ...
Jörk