Ein Graus - File lock
Michel
- cgi
Hi zusammen,
ich weiss, es wurde schon x-mal diskutiert. Nie befriedigend wie ich finde. File locking unter Unix. Schaut Euch das mal an, unter dem Aspekt, dass ich eine Datei lese, den Inhalt auf irgendwas prüfe, den Inhalt veraendere und die Datei dann neu schreibe:
open(DATA, "<datei.dat");
flock (DATA,2);
@temp = <DATA>;
close(DATA);
Ich weiss, dass ich hier ein flock (DATA,1) setzen muesste, ich will aber exclusiv locken. Erstmal egal. Weiter...
$temp[12] = "Neuer text"; # Hier bastel ich also an meinem Inhalt
open(DATA, ">datei.dat"); # und schreib neu
flock (DATA,2);
foreach $mline (@temp) {print DATA $mline . "\n";};
close(DATA);
Soweit so schlecht. Denn was kann alles zwischen den beiden "Open" passieren? Alles! Ich bin ja nicht der einzige Prozess. Ausserdem schuetzt flock (DATA,2) nicht vor einem Lesen der (vielleicht gerade leeren Datei weil geschrieben wird) und und und. Kurz, dieser Code ist Muell.
Simpel: HILFE! WIE IST ES RICHTIG?
Ich hab all das ueber selbst angelegte Semaphoren etc. gelesen, auch das ist keine Lösung. Wie einige richtig erkannt haben gibt es auch dort kritische Momente wo eine Abfrage schieflaufen muss.
Sicher, ich könnte "richtige" Datenbanken nehmen, hab ich aber im Moment nicht und irgendwie muss das doch gehen.
Danke im voraus.
Verzweifelt (Datei schon einmal zerschossen)
Michel
Hallo Michel,
warum nicht so ?
open (FILE,"+<$file") or die # open file
flock(FILE,2); # lock file exclusive
seek (FILE,0,0); # position at start
@records = <LOGFILE>;
... weitere Verarbeitung
seek (FILE,0,0); # position at start
print (FILE @newrecs);
truncate (LOGFILE,tell(LOGFILE));
flock(FILE,8); # release lock
close(FILE);
und in anderen cgis, die nur lesen:
open (FILE,"$file") or die # open file
flock(FILE,1); # lock file shared
... weitere Verarbeitung
viele Grüße Günter
warum nicht so ?
open (FILE,"+<$file") or die # open file
flock(FILE,2); # lock file exclusive
seek (FILE,0,0); # position at start
@records = <LOGFILE>;
[...]
Du meinst @records = <FILE>; richtig?
Ok, ich wuesste nicht warum nicht. Wenn das die absolut sichere Methode ist bin ich Dir sehr dankbar. Ist sie es?
Verstehe nur nicht warum das nicht oefter verwendet wird. Selbst "Profis" schreiben Semaphoren und all das. Z.B. der Author von Webadverts. Den halte ich fuer einigermassen faehig aber er benutzt Semaphoren. Naja, kann sein, dass er flock umgehen will weil manch ein Server das nicht unterstuetzt.
Bis dann
Gruss Michel
Hallo Michel,
Du meinst @records = <FILE>; richtig?
ja, kam von cut&paste ...
Ok, ich wuesste nicht warum nicht. Wenn das die absolut sichere Methode ist bin ich Dir sehr dankbar. Ist sie es?
habe damit noch nie Probleme gehabt (unter Linux) ...
Verstehe nur nicht warum das nicht oefter verwendet wird. Selbst "Profis" schreiben Semaphoren und all das. Z.B. der Author von Webadverts. Den halte ich fuer einigermassen faehig aber er benutzt Semaphoren. Naja, kann sein, dass er flock umgehen will weil manch ein Server das nicht unterstuetzt.
... tja, rätselhaft ... ;-)
Günter
Lieber Günter,
Ok, ich wuesste nicht warum nicht. Wenn das die absolut sichere Methode ist bin ich Dir sehr dankbar. Ist sie es?
habe damit noch nie Probleme gehabt (unter Linux) ...
Viele Zugriffe? Sprich hochfrequentierte Seiten?
Gruss
Michel
Hallo Michel,
Viele Zugriffe? Sprich hochfrequentierte Seiten?
privat eher weniger (purpurhain.de ist nur meine öffentliche Spielwiese und nicht jederman|fraus Geschmack),
im Geschäft - nur Intranet - ca. 20-30 / Min.
Viele Grüße Günter
warum nicht so ?
open (FILE,"+<$file") or die # open file
flock(FILE,2); # lock file exclusive
Da faellt mir noch, flock (FILE,2); sperrt ja nicht das Lesen. Wenn aber ein anderer Prozess hier...
print (FILE @newrecs);
liest waehrend grad geschrieben wird, dann wird der lesende Prozess doch auf jeden Fall unvollstaendige Daten bekommen?
Was meinst Du?
Gruss
Michel
Hallo Michel,
liest waehrend grad geschrieben wird, dann wird der lesende Prozess doch auf jeden Fall unvollstaendige Daten bekommen?
Was meinst Du?
siehe mein 1stes Posting
open (FILE,"$file") or die # open file
flock(FILE,1); # lock file shared
... weitere Verarbeitung
dazu auch ein Auszug aus der Active Perl Dokumentation:
"This means that files locked with flock() may be modified by programs that do not also use flock()."
viele Grüße Günter
warum nicht so ?
open (FILE,"+<$file") or die # open file
[..]
Hi Günter,
und jetzt haette ich noch gern gewusst wie diese Funktion eine Datei erzeugt wenn sie nicht existiert. Das macht sie naemlich nicht.
Ansonsten habe ich sie schon recht erfolgreich am Laufen (bisher ist alles heil geblieben).
Nun habe ich es so geloest, dass ich vorher checke ob die Datei existiert und wenn nicht mit open (FILE, ">>datei.dat");close(FILE); diese erzeuge. Erscheint mir aber nicht sehr elegant.
Da ich zwar ">>" und ">" und "<" verstehe, nicht aber "+<" weiss ich nicht recht was ich machen muss.
Danke!
Gruss
Michel
Hallo Michel,
und jetzt haette ich noch gern gewusst wie diese Funktion eine Datei erzeugt wenn sie nicht existiert. Das macht sie naemlich nicht.
Ansonsten habe ich sie schon recht erfolgreich am Laufen (bisher ist alles heil geblieben).
Nun habe ich es so geloest, dass ich vorher checke ob die Datei existiert und wenn nicht mit open (FILE, ">>datei.dat");close(FILE); diese erzeuge. Erscheint mir aber nicht sehr elegant.
ich wüßte auch keinen besseren Weg als
if(!stat($file))
{
open (FILE,">$file"); # create file
close (FILE;
}
open (FILE,"+<$file") or die();
....
...
..
Da ich zwar ">>" und ">" und "<" verstehe, nicht aber "+<" weiss ich nicht recht was ich machen muss.
Zitat:
If the filename begins with '<' or nothing, the file is opened for input. If the filename begins with '>',
the file is truncated and opened for output, being created if necessary. If the filename begins with
'>>', the file is opened for appending, again being created if necessary. You can put a '+' in front
of the '>' or '<' to indicate that you want both read and write access to the file; thus '+<' is
almost always preferred for read/write updates--the '+>' mode would clobber the file first. You can't
usually use either read-write mode for updating textfiles, since they have variable length records. See the
-i switch in perlrun for a better approach. The file is created with permissions of 0666 modified by the
process' umask value.
Viele Grüße Günter