file handling
Cruz
- perl
Hier noch eine kleine Idee bzw. Frage bezüglich file handling in CGI Scripten.
Der gleichzeitige Dateizugriff ist ein breitgeschlagenes Horrothema. Es gibt eineige Diskussionen im Archiv, aber irgendwie habe ich nirgendwo eine richtig elegante und zuverlässige Lösung entdeckt. Anyways, je kürzer die Zeit des eigentlichen Dateizugriffes, umso wahrscheinlicher, daß kein Konflikt entsteht korrekt? Also hier nun meine Frage, was geht schneller, eine Datei per systemaufruf zu kopieren, oder eine Datein in Perl auszulesen? Ebenso umgekehrt...geht es nicht schneller wenn ich erst eine pre-datei schreibe und sie dann per systemaufruf umbenenne bzw kopiere?
Natürlich ist mir klar, daß es insgesamt nicht schneller geht, da ich ja nicht nur schreibe sondern auch noch kopiere, aber mal die Netto-empfindlichedatei-zugriffszeit betrachtet, kopieren geht schneller oder?
Ich weiß auch, daß sich dies für eine Datenbank nicht gerade eignet, da ein Prozess auf jeden Fall warten muss bis der vorherige prozess fertig ist, damit er eine aktuelle datei lesen kann, aber es gibt bestimmt einige Fälle wo es nützlich sein könnte.
Also?
Cruz
Der gleichzeitige Dateizugriff ist ein breitgeschlagenes Horrothema.
Finde ich nicht. Es *ist* ein Thema - und das nehmen nicht genug Leute wahr.
Es gibt eineige Diskussionen im Archiv, aber irgendwie habe ich nirgendwo eine richtig elegante und zuverlässige Lösung entdeckt.
Kommt darauf an, was man zur Verfügung hat.
Eine Bibliothek mit einem zuverlässigen "test-and-set", und die Sache ist gegessen.
Anyways, je kürzer die Zeit des eigentlichen Dateizugriffes, umso wahrscheinlicher, daß kein Konflikt entsteht korrekt?
Ja, aber es ist eine Frage des Preis-Leistungs-Verhältnisses.
Die Kollisions-Chance von 1% auf 0.9% zu senken, ist mir nicht Faktor 2 an Last für meinen Server wert.
geht es nicht schneller wenn ich erst eine pre-datei schreibe und sie dann per systemaufruf umbenenne bzw kopiere?
Letzteres nützt für Synchronisation gleichzeitiger Schreibzugriffe überhaupt nichts. Wenn zwei Programme schnell genug nacheinander umbenennen, gewinnt der zweite, der vom ersten nichts weiß.
Lustigerweise ist Deine Methode aber für ein ganz anderes Problem sehr hilfreich, nämlich: "Wie stelle ich sicher, daß Programm B eine Datei im vollständigen Zustand lesen kann, welche quasi-gleichzeitig von Programm A erstellt wird?" Da ist Umbenennen genau die Lösung.
Natürlich ist mir klar, daß es insgesamt nicht schneller geht, da ich ja nicht nur schreibe sondern auch noch kopiere, aber mal die Netto-empfindlichedatei-zugriffszeit betrachtet, kopieren geht schneller oder?
Siehe oben (zu teuer).
Ich weiß auch, daß sich dies für eine Datenbank nicht gerade eignet, da ein Prozess auf jeden Fall warten muss bis der vorherige prozess fertig ist, damit er eine aktuelle datei lesen kann, aber es gibt bestimmt einige Fälle wo es nützlich sein könnte.
Na, dann lieber gleich eine richtige Synchronisation schreiben. Das ist zwar aufwendiger, wenn man es selbst machen muß, aber einmal programmiert und immer wieder verwendet müßte sich das lohnen.
Gibt es so etwas vielleicht schon in CPAN?
Was ich haben wollen würde, wäre eine Funktion, die eben unteilbar eine Test- und eine Set-Operation durchführt und als Returncode zurückliefert, ob sie aufgrund des Test-Ergebnisses befugt war, die Set-Operation durchzuführen (und diese ist zu diesem Zeitpunkt auch bereits durchgeführt!).
Wenn man so etwas hätte, würde sich jede Synchronisation reduzieren auf
until (test_and_set ($semaphor_path))
{sleep ($some_random_time)};
# ab hier sind wir drin, und zwar alleine!
Das Problem ist, daß der Modul, der eine solche Information verwaltet, ein prozeßübergreifendes Gedächtnis braucht. In C geht so etwas vermutlich über irgendwelche shared memory-Segmente, aber bei Perl fällt mir nichts Passendes ein, wie man das lösen würde. Auf das Dateisystem möchte ich in diesem Kontext eher ungern zurückgreifen.
BTW: Auf dem gute, uralten IBM-Großhobel ist so etwas einfach schon ein Maschinenbefehl ...
Gibt es so etwas vielleicht schon in CPAN?
Hm, ich habe dort mal nach "semaphore" gesucht, und immerhin: Für Win32 (!) gibt es einen Modul, der Perl die Windows-eigenen Semaphore zur Verfügung stellt. (http://search.cpan.org/doc/GSAR/libwin32-0.151/blib/lib/Win32/Semaphore.pm)
Damit müßte eine saubere Synchronisation relativ einfach zu machen sein, wenn man die Funktionen mal verstanden hat.
So, und jetzt das Ganze noch plattformunabhängig - wie könnte das bloß heißen ... "synchronization" liefert auch bloß Win32::IPC ...
Hier noch eine kleine Idee bzw. Frage bezüglich file handling in CGI Scripten.
Der gleichzeitige Dateizugriff ist ein breitgeschlagenes Horrothema. Es gibt eineige Diskussionen im Archiv, aber irgendwie habe ich nirgendwo eine richtig elegante und zuverlässige Lösung entdeckt. Anyways, je kürzer die Zeit des eigentlichen Dateizugriffes, umso wahrscheinlicher, daß kein Konflikt entsteht korrekt?
Kurze Zugriffszeiten sind _kein_ effektiver Schutz vor gleichzeitigem Zugriff. Benutze lieber Filelocking.
cu,
Peter