Christian Seiler: Neuer Artikel: Sperren von Dateien

Hallo allerseits,

Ich habe einen neuen Artikel geschrieben: Sperren von Dateien.

Siehe auch den zugehörigen Weblog-Eintrag.

Viele Grüße,
Christian

  1. Hallo Christian,

    Ich habe einen neuen Artikel geschrieben: Sperren von Dateien.

    prima, das ist ein Thema, das immer wieder auftaucht und dessen Wichtigkeit regelmäßig unterschätzt wird.
    Schade jedoch, dass du den Artikel in so viele Einzelseiten zerteilt hast; das macht ihn meiner Ansicht nach unübersichtlich und etwas unhandlich.

    Unter Windows kann eine Datei übrigens nicht nur über LockFileEx() gesperrt werden, sondern auch über den ShareMode-Parameter der Funktion CreateFile(). Das ist dann sogar unabhängig vom Filesystem und funktioniert nicht nur auf NTFS, sondern auch auf FAT-Volumes.

    Schönes Wochenende noch,
     Martin

    --
    Lieber eine Fliege im Porzellanladen
    als ein Elefant in der Suppe.
    1. Hallo Martin,

      Schade jedoch, dass du den Artikel in so viele Einzelseiten zerteilt hast; das macht ihn meiner Ansicht nach unübersichtlich und etwas unhandlich.

      *LOL* - ich hatte das ursprünglich als eine große Seite und dann hat Siechfred gemeint, die wäre ein Monstrum, in dem man sich nicht zurechtfinden würde, also hab ich ihn aufgeteilt. Man kann's wohl keinem Recht machen. ;-)

      Unter Windows kann eine Datei übrigens nicht nur über LockFileEx() gesperrt werden, sondern auch über den ShareMode-Parameter der Funktion CreateFile(). Das ist dann sogar unabhängig vom Filesystem und funktioniert nicht nur auf NTFS, sondern auch auf FAT-Volumes.

      Ja, ich weiß - wobei ShareMode etwas leicht anderes ist, als "klassisches" Locking (und ich auch gerade nicht auswendig weiß, was da bei Netzwerkdateisystemen passiert, wenn unterschiedliche Rechner das machen wollen). Das Problem an ShareMode ist, dass alle 4 hier vorgestellten Programmiersprachen das in der Form nicht unterstützen (zumindest nicht ohne Extra-Module) und - weil's eben direkt bei Open angegeben werden muss - nicht portabel ist.

      Zudem: Ich denke jeder, der ernsthaft einen Windows-Server betreibt, hat heutzutage NTFS, daher halte ich das ganze für kein wirkliches Problem.

      Viele Grüße,
      Christian

      1. Hallo,

        Schade jedoch, dass du den Artikel in so viele Einzelseiten zerteilt hast
        Man kann's wohl keinem Recht machen. ;-)

        das ist natürlich wahr, ich hatte auch nur meinen Eindruck wiedergegeben. Ich habe größere Informationsmengen halt lieber am Stück, das ist einfach praktischer in der Handhabung (speichern, drucken, in andere Formate umsetzen).

        Unter Windows kann eine Datei übrigens nicht nur über LockFileEx() gesperrt werden, sondern auch über den ShareMode-Parameter der Funktion CreateFile().
        Ja, ich weiß

        Gut. Dein Artikel las sich so, als würdest du behaupten, dass LockFileEx() die einzige Möglichkeit sei.

        (und ich auch gerade nicht auswendig weiß, was da bei Netzwerkdateisystemen passiert, wenn unterschiedliche Rechner das machen wollen).

        Nichts. Jedenfalls aus der Sicht des Windows-Rechners. Bei Netzwerkvolumes überlässt Windows das Locking komplett dem Host, dem das Dateisystem gehört. Ist das bei den anderen nicht auch so? Kann ein Linux-Host von sich aus eine Datei für den Zugriff sperren, die auf einem anderen Host liegt? Oder macht das nicht in Wirklichkeit auch der Server, der die Datei zur Verfügung stellt?

        Zudem: Ich denke jeder, der ernsthaft einen Windows-Server betreibt, hat heutzutage NTFS

        Da hast du wahrscheinlich Recht, aber die Problematik des File-Lockings besteht ja nicht nur in Server-Umgebungen, sondern auch bei lokalen Anwendungen, die konkurrierend auf dieselbe Datei zugreifen wollen (oder sogar konkurrierende Threads innerhalb einer Anwendung). Daher ist das Thema sogar für die Nur-Windows-Programmierer interessant.

        So long,
         Martin

        --
        F: Was sagt der große Keks zum kleinen Keks?
        A: Du kannst dich jetzt verkrümeln.
        1. Hallo Martin,

          (und ich auch gerade nicht auswendig weiß, was da bei Netzwerkdateisystemen passiert, wenn unterschiedliche Rechner das machen wollen).

          Nichts. Jedenfalls aus der Sicht des Windows-Rechners. Bei Netzwerkvolumes überlässt Windows das Locking komplett dem Host, dem das Dateisystem gehört. Ist das bei den anderen nicht auch so? Kann ein Linux-Host von sich aus eine Datei für den Zugriff sperren, die auf einem anderen Host liegt? Oder macht das nicht in Wirklichkeit auch der Server, der die Datei zur Verfügung stellt?

          Ich verstehe nicht ganz, was Du jetzt wie meinst.

          Folgende Situation (egal ob jetzt Linux oder Windows und ob jetzt SMB oder NFS): Rechner A ist der "Server", Rechner B und C sind die "Clients" (im SMB/NFS-Sinn). Sprich: Rechner A gibt irgend ein Verzeichnis frei, das auf Rechnern B und C eingebunden ist.

          Nun sperrt ein Programm auf Rechner B eine Datei, die eigentlich auf Rechner A liegt. Was passiert, wenn ein Programm auf Rechner C nun die selbe Datei sperren will?

          Im folgenden werde ich folgende Begriffe nutzen:

          "Funktioniert" == Rechner C muss warten
           "Funktionier nicht" == Rechner C denkt, er habe die Datei gesperrt
                                  (d.h. die Sperren sind unabhängig voneinander nur
                                  auf den jeweiligen Rechnern vorhanden und daher
                                  kann es zu Konflikten Kommen)
           "Fehler" == auf Rechner C tritt eine Fehlermeldung auf

          [Den Fall, in denen gar keine Rechner überhaupt Dateien sperren können, weil Funktionalität deaktiviert oder ähnliches, betrachte ich hier mal nicht.]

          Was passiert nun?

          * Windows/LockFileEx: "Funktioniert"
           * Linux/flock(2) (und vmtl. auch FreeBSD/flock(2) und MacOSX/flock(2):
             "Funktioniert nicht"
           * Linux/fcntl(2) (und vmtl. auch FreeBSD/fcntl(2) und MacOSX/fcntl(2):
             "Funktioniert"

          Meine Klammer bezog sich nun darauf, dass ich weder recherchiert noch getestet habe, was unter Windows mit den Share-Modes passiert, wenn diese über das Netzwerk verwendet werden. Wäre also nett, wenn Du sagen kannst, in welchen der drei obigen Fälle folgendes Szenario passt:

          Rechner A, B und C sind Windows-Rechner (2000, 2003 oder XP z.B.). Auf Rechner B öffnet ein Prozess eine Datei auf Rechner A mit ShareMode == "ich teile gar nichts" und kurz darauf während die Datei noch offen ist versucht ein Prozess auf Rechner C die selbe Datei auch mit ShareMode == "ich teile gar nichts" zu öffnen. Was passiert hier?

          Zudem: Ich denke jeder, der ernsthaft einen Windows-Server betreibt, hat heutzutage NTFS

          Da hast du wahrscheinlich Recht, aber die Problematik des File-Lockings besteht ja nicht nur in Server-Umgebungen, sondern auch bei lokalen Anwendungen, die konkurrierend auf dieselbe Datei zugreifen wollen (oder sogar konkurrierende Threads innerhalb einer Anwendung). Daher ist das Thema sogar für die Nur-Windows-Programmierer interessant.

          Ja klar. Nur wenn das meine Zielgruppe gewesen wäre, dann hätte ich einen Abschnitt über C hinzugefügt, der die Windows-API-Funktion selbst erläutert. ;-) Und dann hätte ich CreateFile auch besprochen - und die damit verbundenen ShareModes.

          Viele Grüße,
          Christian

          1. Hallo Christian,

            Ich verstehe nicht ganz, was Du jetzt wie meinst.

            und dabei ist es doch gar nicht so kompliziert. ;-)

            Folgende Situation (egal ob jetzt Linux oder Windows und ob jetzt SMB oder NFS): Rechner A ist der "Server", Rechner B und C sind die "Clients" (im SMB/NFS-Sinn). Sprich: Rechner A gibt irgend ein Verzeichnis frei, das auf Rechnern B und C eingebunden ist.

            Klar soweit.

            Nun sperrt ein Programm auf Rechner B eine Datei, die eigentlich auf Rechner A liegt. Was passiert, wenn ein Programm auf Rechner C nun die selbe Datei sperren will?

            Das Ergebnis ist dasselbe, als wenn Rechner A, B und C identisch wären, die Datei also auf derselben Maschine liegt wie die beiden konkurrierenden Client-Applikationen.

            [Den Fall, in denen gar keine Rechner überhaupt Dateien sperren können, weil Funktionalität deaktiviert oder ähnliches, betrachte ich hier mal nicht.]

            Logisch. :-)

            Rechner A, B und C sind Windows-Rechner (2000, 2003 oder XP z.B.). Auf Rechner B öffnet ein Prozess eine Datei auf Rechner A mit ShareMode == "ich teile gar nichts" und kurz darauf während die Datei noch offen ist versucht ein Prozess auf Rechner C die selbe Datei auch mit ShareMode == "ich teile gar nichts" zu öffnen. Was passiert hier?

            Unter Windows bekommt Rechner/Prozess C eine Fehlermeldung (Sharing Violation) und muss den Zugriff selbständig wiederholen. Ein "Warte bis Datei freigegeben" gibt es unter Windows AFAIK nicht, wenn es nicht auf Anwendungsebene implementiert wird.

            Ich wollte nur darauf hinaus, dass in deinem Szenario nicht die Clients B und C die Locks verwalten, sondern logischerweise der Server A. Die beiden Clients "reichen nur durch".
            Selbst wenn auf Rechner B noch zwei Applikationen um den Zugriff konkurrieren würden und das OS (Windows) auf Rechner B theoretisch schon einen Konflikt feststellen könnte, reicht es beide Zugriffe an Rechner A weiter und lässt ihn den Konflikt feststellen.

            Nur wenn das meine Zielgruppe gewesen wäre, dann hätte ich einen Abschnitt über C hinzugefügt

            Den habe ich irgendwie vermisst. Denn der Artikel ist mit "Sperren von Dateien" überschrieben, auch die Einleitung ist zunächst allgemein gehalten. Dann gehst du auf vier sehr konkrete, spezielle Sprachen ein, ohne die Problematik zunächst allgemein sprachunabhängig zu beleuchten.

            Ich meine, das ist völlig legitim so. Aber dann sollte der Titel vielleicht schon auf die spezielle Ausrichtung auf Web-typische Sprachen hinweisen.

            Schönen Abend noch,
             Martin

            --
            Lieber eine Fliege im Porzellanladen
            als ein Elefant in der Suppe.
            1. Hello,

              Unter Windows bekommt Rechner/Prozess C eine Fehlermeldung (Sharing Violation) und muss den Zugriff selbständig wiederholen. Ein "Warte bis Datei freigegeben" gibt es unter Windows AFAIK nicht, wenn es nicht auf Anwendungsebene implementiert wird.

              Ich weiß nur noch auswendig, wie es bei Windows 98 war, bzw beim Zusammenspiel von DOS und NOVELL.

              Dos bekam durch die Netzwerkshell eine Erweiterung des Int 21h für die Netzwerkzugriffe. Diese wurden dann über die Shell an den Server gesandt und dort umgestezt. Ein Warten gab es nicht.

              "Filemode 2" war der alte Öffnungsmode für rdwr-lock
              Durch setzen des share-flags konnte man dann sagen, ich teile die Datei mit anderen und durch setzen der share bzw exclusive-Flags konnte man dann genau das erreichen, was man heute auch erreichen kann.

              Und ein bisschen alten Code für eine eigene NOVELL-API auf DOS  habe ich auch noch  gefunden ;-)
              Es gab also beim Record-Locking eine Wartezeit, die man in Ticks vorgeben konnte.
              Hier ein kleiner Ausschnitt...

              Function NewRecLock(Var DataBase : File;
                                      Pos      : Longint;
                                      Len      : Longint;
                                      LOCK     : Boolean;
                                      EXCL     : Boolean;
                                      TIMEOUT  : Word ) :Word;
              var
                Regs        : Registers;
                Flags       : Byte;
              begin
                Regs.AH := $BC;       { Funktion Log Physical Record }

              Flags := 0;
                If Lock then Flags := (Flags or 1);
                If not EXCL then Flags := (Flags or 2); { Bit 1 setzen für Non-Excl }
                Regs.AL := Flags;
                Regs.BX := FileRec(Database).Handle;

              Regs.CX := DWord(Pos).HiWord;   { Position des Records im File }
                Regs.DX := DWord(Pos).LoWord;

              Regs.SI := DWord(Len).HiWord;   { Länge des Records }
                Regs.DI := DWord(Len).LoWord;

              Regs.BP := TimeOut;             { Wartezeit in Ticks, für Lockversuch }

              MsDos(Regs);

              case Regs.AL of
                   0: NewRecLock := 0;
                 $96: NewRecLock := 90;         { zu wenig dynamischer Speicher im Server }
                 $FE: NewRecLock := 91;         { Time-Out-Fehler }
                 $FF: NewRecLock := 92;         { Sperrversuch abgewiesesen, "FAILED" }
                 else NewRecLock := 59;         { Nichterkundbarer Netzwerkfehler }
                end; { Case Regs.AL }
              end;

              Wenn ich noch ein bisschen weiterkrame, finde ich die Files für Windows (bis NT 4.0) sicher auch noch.

              Harzliche Grüße vom Berg
              http://bergpost.annerschbarrich.de

              Tom

              --
              Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
              Nur selber lernen macht schlau
              Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            2. Hallo Martin,

              Unter Windows bekommt Rechner/Prozess C eine Fehlermeldung (Sharing Violation) und muss den Zugriff selbständig wiederholen.

              Also der Fall "Fehler" bei meiner obigen Ausführung. Das macht die Sharing-Methode zumindest sehr umständlich zu benutzen, da man das "ich probiere es selbst wieder" implementieren muss.

              Ein "Warte bis Datei freigegeben" gibt es unter Windows AFAIK nicht, wenn es nicht auf Anwendungsebene implementiert wird.

              Doch: Bei LockFileEx wird (bei entsprechend gesetzten Parametern) darauf gewartet, bis das Lock wieder frei wird, bevor die Funktion zurückkehrt.

              Viele Grüße,
              Christian

  2. Ich habe einen neuen Artikel geschrieben: Sperren von Dateien.

    Großartig, vielen Dank!

    Viele Grüße!
    _ds

    --
    »Die Affinität zur Warenausgabe verläuft reziprok zur Verfügung stehenden Freizeit der Greisin.«
    - Das kleine Seitenschwein, Drängelcharakter
  3. Hallo,

    Ich habe einen neuen Artikel geschrieben: Sperren von Dateien.

    Ich sag einfach mal Danke!

    Viele Grüße,
    Hotte

    , schreibt auch grade einen Artikel...

    1. Viele Grüße,
      Hotte

      , schreibt auch grade einen Artikel...

      Hier isser:

      http://rolfrost.de/control.html

      Viel Spass damit und viele Grüße,
      Horst Haselhuhn

  4. Hello,

    Ich habe einen neuen Artikel geschrieben: Sperren von Dateien.

    Sehr lobenswert!

    Anmerkung zum PHP-Teil:

    if (!flock ($fp, LOCK_EX)) {
      die ('Sperren der Datei fehlgeschlagen!');

    Bist Du sicher, dass das die überhaupt noch ausgeführt wird?
    MMn wartet das flock() solange, bis es Erfolg hat, oder aber das PHP-Timeout zuschlägt.

    Und _wenn_ die() hier jemals ausgeführt würde, wäre es nicht unbedingt geschickt, ein größeres Skript derartig abzubrechen. Es sollte dann eine qualifizierte Fehlerbehandlung stattfinden, die den User nicht in den Wald stellt.

    Leider sind solche ja durchaus "funzenden" Beispiele geeignet, sich über den Weg des Copy & Paste beliebig oft zu vervielfältigen und sich dann als Standart (sic!) zu etablieren.

    Wenn Du es also nicht als allzu unverschämt empfindest, würde ich an diesen Stellen gerne "nachrüsten" und zumindest vernünftige Funktionen mit qualifizierter Fehlerbehandlung dafür vorschlagen.

    Ein paar Grafiken würden die Sache sicher noch verständlicher machen, aber dafür bin ich leider nicht der passende Künstler.

    Noch eine Frage zu touch(), und den anderen namensbasierten Dateifunktionen:

    Hat schonmal jemand ausprobiert, was die machen, wenn es auf ein Advisory Lock laufen?
    Eigentlich sollte sowas im PHP-Manual dokumentiert sein, aber ich konnte bisher nie etwas finden zu dem Thema. Nur bei file_put_contents() http://de2.php.net/manual/de/function.file-put-contents.php ist da inzwischen 'was eingebaut.

    Harzliche Grüße vom Berg
    http://bergpost.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    1. Hallo,

      Anmerkung zum PHP-Teil:

      if (!flock ($fp, LOCK_EX)) {
        die ('Sperren der Datei fehlgeschlagen!');

      Bist Du sicher, dass das die überhaupt noch ausgeführt wird?
      MMn wartet das flock() solange, bis es Erfolg hat, oder aber das PHP-Timeout zuschlägt.

      Nein, das ist vollkommen falsch. flock() wartet grundsätzlich, bis es Erfolg hat. Das PHP-Timeout (Du meinst set_time_limit() bzw. die entsprechende ini-Einstellung, nehme ich an?) schlägt bei Systemaufrufen nämlich in KEINEM Fall zu! Die einzige Möglichkeit, flock() zu unterbrechen, ist ein nicht-ignoriertes Signal an den Prozess zu schicken. Aber solange man kein Deadlock produziert, ist es eigentlich nie ein Problem, auf eine Sperre zu warten, denn irgendwann wird die schon wieder frei werden.

      Also: Es gibt 3 Möglichkeiten:

      a) Der Aufruf kehrt zurück und die Sperre wurde etabliert
       b) Der Aufruf kehrt nicht zurück und der Prozess wartet ewig
          (falls eben ein Deadlock auftritt)
       c) Der Aufruf kehrt zurück und ein Fehler beim Sperren ist aufgetreten.
          Dies kann zum Beispiel passieren, wenn man fopen-Wrapper verwendet
          und versucht, eine Datei über FTP zu öffnen - da funktioniert das
          Sperren nämlich gar nicht (FTP kann so etwas nicht). Oder es kann
          passieren, wenn man's unter Windows 98 versucht.

      Und genau den Fall (c) soll die die()-Abfrage abfangen. Nicht mehr, nicht weniger.

      Und _wenn_ die() hier jemals ausgeführt würde, wäre es nicht unbedingt geschickt, ein größeres Skript derartig abzubrechen. Es sollte dann eine qualifizierte Fehlerbehandlung stattfinden, die den User nicht in den Wald stellt.

      Natürlich sollte in größeren Scripten bessere Fehlerbehandlungsmöglichkeiten existieren, aber dies ist explizit ein einfaches Beispiel. Wer ein größeres Script schreibt und sich bereits Gedanken um Fehlerbehandlung gemacht hat, wird ja wohl selbst noch erkennen, dass die() in dem Kontext keine gute Wahl ist und das von selbst ersetzen.

      Ich wollte das Beispiel möglichst einfach halten, so dass wirklich nur der eigentliche Sachverhalt dargestellt wird - und bei diesen einfachen Beispielen, die nichts anderes tun, funktioniert die Fehlerbehandlung über die() zufriedenstellend. Wenn ich dort jetzt noch eine ausgereifte Fehlerbehandlung einbauen würde, dann würde ich das Beispiel nur unnötig verkomplizieren. Zumal es bei ausgereifter Fehlerbehandlung wieder unterschiedliche Geschmäcker gibt: Exceptions, bestimmte Rückgabewerte, einen User-Error mit PHP werfen, usw. usf. Sorry, aber das ist schlichtweg nicht das Thema des Artikels.

      Leider sind solche ja durchaus "funzenden" Beispiele geeignet, sich über den Weg des Copy & Paste beliebig oft zu vervielfältigen und sich dann als Standart (sic!) zu etablieren.

      Ich habe kein Problem damit, wenn sich der aktuelle Code als Standard etablieren würde, denn ich kann Deine Kritik nicht nachvollziehen (s.o.).

      Noch eine Frage zu touch(), und den anderen namensbasierten Dateifunktionen:

      Hat schonmal jemand ausprobiert, was die machen, wenn es auf ein Advisory Lock laufen?

      Sie funktionieren weiterhin. Das musst Du auch nicht ausprobieren, denn (und das steht übrigens auch in meinem Artikel drin) ein Advisory Lock ist eben "freiwillig", d.h. bei Advisory Locking kann ein Programm, das den Locking-Mechanismus nicht nutzt, beliebiges mit der Datei anstellen.

      Und selbst bei Mandatory Locks unter Windows ist touch() kein Problem, da es ja explizit nichts in die Datei schreibt oder daraus liest - und das reine Öffnen (solange man die Datei nicht dabei zerstört) ist weiterhin problemlos erlaubt - auch bei Mandatory Locking. file_put_contents() oder ähnliches wird halt bei Mandatory Locking versagen.

      Viele Grüße,
      Christian

      1. Hallo nochmal,

        file_put_contents() oder ähnliches wird halt bei Mandatory Locking versagen.

        Oh, das hatte ich überlesen, das hat das wohl inzwischen Locks eingebaut.

        Allerdings habe ich mir gerade den Sourcecode angesehen und schwupp... die PHP-Leute haben's natürlich falsch gemacht. In PHP 5.2.4 steht nämlich (ext/standard/file.c):

                stream = php_stream_open_wrapper_ex(filename, (flags & PHP_FILE_APPEND) ? "ab" : "wb",  
                                ((flags & PHP_FILE_USE_INCLUDE_PATH) ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context);  
                if (stream == NULL) {  
                        RETURN_FALSE;  
                }  
          
                if (flags & LOCK_EX && php_stream_lock(stream, LOCK_EX)) {  
                        php_stream_close(stream);  
                        RETURN_FALSE;  
                }
        

        Das heißt, sie machen gerade "Dateien zum Schreiben öffnen" falsch. Mal Testcase schreiben und als Bug melden.

        Also ist meine Aussage, dass es bei Mandatory Locking versagen wird, wohl doch nicht ganz falsch - obwohl's inzwischen "im Prinzip" nicht versagen sollte...

        Viele Grüße,
        Christian

        1. Hallo,

          [PHP: file_put_contents + LOCK_EX]
          Mal Testcase schreiben und als Bug melden.

          Zur Info: Ich habe den Bug bei PHP mal gemeldet.

          http://bugs.php.net/bug.php?id=43182

          Viele Grüße,
          Christian

      2. Hello,

        if (!flock ($fp, LOCK_EX)) {
          die ('Sperren der Datei fehlgeschlagen!');
        }

        Also: Es gibt 3 Möglichkeiten:

        c) Der Aufruf kehrt zurück und ein Fehler beim Sperren ist aufgetreten.
            Dies kann zum Beispiel passieren, wenn man fopen-Wrapper verwendet
            und versucht, eine Datei über FTP zu öffnen - da funktioniert das
            Sperren nämlich gar nicht (FTP kann so etwas nicht). Oder es kann
            passieren, wenn man's unter Windows 98 versucht.

        Die Möglichkeit habe ich eben nicht bedacht, das stimmt.
        Meine Überlegung war "Wenn fopen() versagt (die Datei nicht da ist), gehe ich gar nicht zum flock()".
        Aber das ist eben nicht zuende gedacht, weil die Datei zwischen dem erfolgreichen fopen() und dem flock() auch schon wieder verschwunden sein könnte oder sonstiges...

        Bleibt noch eine Frage: Was macht flock( ...   LOCK_EX + LOCK_NB), wenn bereits ein dio_lock gesetzt ist? Theoretisch könnte es ja sagen: Lockanfoerderung nicht möglich, aber ich glaube, es wartet trotzdem (so war es bei PHP4).

        Kannst Du das ausprobieren oder besser auch nachschauen?

        Harzliche Grüße vom Berg
        http://bergpost.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

        1. Hallo,

          Aber das ist eben nicht zuende gedacht, weil die Datei zwischen dem erfolgreichen fopen() und dem flock() auch schon wieder verschwunden sein könnte oder sonstiges...

          Wenn der Dateiname weg ist, versagt flock() deswegen trotzdem nicht (unter UNIX-artigen Betriebssystemen), sondern sperrt die Datei weiterhin (unter UNIX-artigen Betriebssystemen sind Dateien nicht zwangsläufig an Namen gebunden!) und unter Windows kannst Du eine Datei, die geöffnet wurde, nicht löschen.

          Bleibt noch eine Frage: Was macht flock( ...   LOCK_EX + LOCK_NB), wenn bereits ein dio_lock gesetzt ist?

          Es bekommt die Sperre. Das würde auch nur mit LOCK_EX gehen. Wie auch in meinem Artikel erwähnt ist, nutzt dio_fcntl die Funktion fcntl(2) während flock in der Regel flock(2) nutzt, die aber vollkommen unabhängig voneinander sind.

          Theoretisch könnte es ja sagen: Lockanfoerderung nicht möglich, aber ich glaube, es wartet trotzdem (so war es bei PHP4).

          Wenn Du NB setzt, wartet gar nichts. Definitiv nihct. Und die Sperre ist möglich, weil's eine komplett verschiede Sperre ist, als die andere Funktion. Deswegen muss man auch beim programmiersprachenübergreifenden Sperren von Dateien höllisch aufpassen.

          Kannst Du das ausprobieren oder besser auch nachschauen?

          Ich muss weder noch - ich hab's ja genau so, wie ich in diesem Posting noch einmal ausgeführt habe, erst in den Artikel geschrieben (vgl. die Abschnitte über die Betriebsysteminterna mit dem PHP-Abschnitt mit dem Abschnitt über programmiersprachenübergreifende Sperren). Mich beschleicht langsam das Gefühl, Du hättest den nicht vollständig gelesen, sondern nur überflogen...

          Viele Grüße,
          Christian

          1. Hello,

            Kannst Du das ausprobieren oder besser auch nachschauen?

            Ich muss weder noch

            Es war auch nur eine Bitte.

            (Ich kann es z.Zt. nur mit PHP4 ausprobieren, und das ist ja witzlos, denn da wurde
            definitv totzdem gewartet, auch wenn extra NonBlocking gewünscht wurde.)

            Harzliche Grüße vom Berg
            http://bergpost.annerschbarrich.de

            Tom

            --
            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
            Nur selber lernen macht schlau
            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

            1. Hallo Tom,

              (Ich kann es z.Zt. nur mit PHP4 ausprobieren, und das ist ja witzlos, denn da wurde
              definitv totzdem gewartet, auch wenn extra NonBlocking gewünscht wurde.)

              Sorry, aber das kann ich mir nicht vorstellen. Wie hast Du das denn getestet?

              Folgender Testcase: Erste PHP-Datei:

              <?php  
                
              $fp = dio_open ('file.txt', O_WRONLY | O_CREAT, 0666);  
              var_dump ($fp);  
              $res = dio_fcntl ($fp, F_SETLKW, array ('start' => 0, 'length' => 0, 'whence' => SEEK_SET, 'type' => F_WRLCK));  
              var_dump ($res);  
              sleep (20);  
              dio_close ($fp);  
                
              ?>
              

              Zweite PHP-Datei:

              <?php  
                
              $fp = fopen ('file.txt', 'r+');  
              var_dump ($fp);  
              $res = flock ($fp, LOCK_EX);  
              var_dump ($res);  
              fclose ($fp);  
                
              $fp = fopen ('file.txt', 'r+');  
              var_dump ($fp);  
              $res = flock ($fp, LOCK_EX | LOCK_NB);  
              var_dump ($res);  
              fclose ($fp);  
                
              ?>
              

              Erste führst Du in einem Fenster auf, da sollte folgende Ausgabe erscheinen:

              resource(4) of type (Direct I/O File Descriptor)
              int(0)

              (1. Zeile auf jeden Fall resource(X) und zweite Zeile auf jeden Fall int(0))

              Zweite führst du während die erste noch schläft in einem zweiten Fenster aus, dann sollte sowas rauskommen:

              resource(5) of type (stream)
              bool(true)
              resource(6) of type (stream)
              bool(true)

              (1. und 3. Zeile auf jeden Fall resource(X) und zweite und vierte Zeile auf jeden Fall bool(true)!)

              Und das zweite Script sollte sich SOFORT beenden, d.h. auf GAR NICHTS warten.

              Eben weil beide Lock-Typen (fcntl(2) und flock(2)) vollkommen unterschiedlich sind und nichts miteinander zu tun haben.

              Der EINZIGE Fall, in dem auch nur IRGENDETWAS warten könnte, wäre, wenn Du Mandatory Locks aktiviert hast, d.h. das Dateisystem mit -o mand gemountet hast und das SetGid-Bid bei deaktiviertem Group-Executable-Bit der betroffenen Datei aktiviert hast - das allerdings auch nicht bei diesem Beispiel (das die Datei nur zum Lesen öffnet), sondern dann bei konkreten Lese- und Schreibvorgängen.

              Viele Grüße,
              Christian

              1. Hello,

                Danke für den Test.

                So (ähnlich) hatte ich es gemacht.

                Ich muss mich erstmal orientieren, ob ich bei PHP 5.2.0 noch mit --enable-dio neu compilieren muss oder ob ich jetzt die von Dir erwähnte Erweiterung nutzen kann.

                Dann werde ich es selber nochmal ausprobieren und dann auch nochmal mit Deinem Test auf dem alten System. Vielleidht hatte ich wirklich nur was falsch gemacht. Die Dateien sind leider nur auf der alten Platte. Ich gucke aber nachher nach.

                Der EINZIGE Fall, in dem auch nur IRGENDETWAS warten könnte, wäre, wenn Du Mandatory Locks aktiviert hast, d.h. das Dateisystem mit -o mand gemountet hast

                so ist es

                und das SetGid-Bid bei deaktiviertem Group-Executable-Bit der betroffenen Datei aktiviert hast - das allerdings auch nicht bei diesem Beispiel (das die Datei nur zum Lesen öffnet), sondern dann bei konkreten Lese- und Schreibvorgängen.

                DAS muss ich allerdings erstmal verdauen. Wodurch steuere ich das? Kann das unter Normalumständen aus Versehen passieren?

                Harzliche Grüße vom Berg
                http://bergpost.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau
                Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                1. Hallo Tom,

                  [PHP 5.1 + dio]

                  Das gibt's wie gesagt nur noch als nicht mehr gewartete Erweiterung. Installationsanleitungen sind übrigens:

                  cvs -d :pserver:cvsread@cvs.php.net:/repository co pecl/dio
                  cd pecl/dio
                  phpize
                  ./configure
                  make
                  make install

                  [mandatory locking ]
                  DAS muss ich allerdings erstmal verdauen. Wodurch steuere ich das? Kann das unter Normalumständen aus Versehen passieren?

                  DASS Du -o mand verwendet hast UND die Bits Deiner Testdatei zufälligerweise so gesetzt hast? Möglich, aber EXTREM unwahrscheinlich.

                  Viele Grüße,
                  Christian

                  1. Hello,

                    [PHP 5.1 + dio]

                    Das gibt's wie gesagt nur noch als nicht mehr gewartete Erweiterung. Installationsanleitungen sind übrigens:

                    cvs -d :pserver:cvsread@cvs.php.net:/repository co pecl/dio
                    cd pecl/dio
                    phpize
                    ./configure
                    make
                    make install

                    Danke, Du kannst wohl Gedanken lesen?
                    Ich suche schon die ganze Zeit, wo ich die PECL-Erweiterung downloaden kann.
                    Unter http://pecl.php.net/package/dio ist leider im Moment nichts zu holen.

                    [mandatory locking ]
                    DAS muss ich allerdings erstmal verdauen. Wodurch steuere ich das? Kann das unter Normalumständen aus Versehen passieren?

                    DASS Du -o mand verwendet hast UND die Bits Deiner Testdatei zufälligerweise so gesetzt hast? Möglich, aber EXTREM unwahrscheinlich.

                    die Mount-Option war selbstverständlich absichtlich, sonst funktioniert es doch gar nicht (?).

                    Bis das wieder alles so läuft, wie auf dem alten Server, eben nur mit den neuen Versionen, das ziiiiieht sich hin. Alleine macht mir das auch immer nicht so viel Spaß. Dabei kann man um diese Jahreszeit kaum 'was anderes machen, wenn man nciht mit den Kindern der Nachbarn Laterne laufen will. :-)

                    Harzliche Grüße vom Berg
                    http://bergpost.annerschbarrich.de

                    Tom

                    --
                    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                    Nur selber lernen macht schlau
                    Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                    1. Hello,

                      cvs -d :pserver:cvsread@cvs.php.net:/repository co pecl/dio
                      cd pecl/dio
                      phpize
                      ./configure
                      make
                      make install

                      Ich krieg die losen Enden nicht zusammen! :-((
                      CVS ist drauf und tut's
                      Sourcen hatte ich vorhin beschafft und unter /opt/src/php-5.2.4 geparkt
                      das DIO-PECL ligt nun fröhlich unter /root/cvs/pecl/dio

                      Leider habe ich kein funktionstüchtiges phpize
                      Es gibt aber

                      - phpize.in
                        - phpize.m4
                        - phpize.1.in

                      phpize.in sieht ja ganz gut aus...
                      kann ich das gebrauchen?

                      Ich habe das PHP nicht auf der Kiste gebaut, sondern fertig per apt-get geholt.

                      Mit welcher Aktion kommt / entsteht phpize?

                      Harzliche Grüße vom Berg
                      http://bergpost.annerschbarrich.de

                      Tom

                      --
                      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                      Nur selber lernen macht schlau
                      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                      1. Hallo,

                        Sourcen hatte ich vorhin beschafft und unter /opt/src/php-5.2.4 geparkt

                        Wenn Du, wie Du weiter unten schreibst, PHP über apt-get installiert hast, dann nutzen Dir die PHP-Sourcen selbst nicht viel.

                        Ich habe das PHP nicht auf der Kiste gebaut, sondern fertig per apt-get geholt.

                        Dann spaltet die Distribution, die Du hast, PHP in verschiedene Pakete auf. Das Paket, in dem phpize enthalten ist, ist bei Dir offensichtlich nicht installiert. Suche mal nach einem Paket, das auf '-dev' endet, z.B. 'php-dev' oder ähnliches... Wenn das installiert ist, gibt's auch phpize. Bzw. ich sehe gerade, dass bei Debian das Paket 'php5-dev' heißt und das dann nicht 'phpize', sondern 'phpize5' heißt (die benennen das wohl auf Grund von Kompabilität mit PHP4 um).

                        Viele Grüße,
                        Christian

                        1. Hello Christian,

                          Dann spaltet die Distribution, die Du hast, PHP in verschiedene Pakete auf. Das Paket, in dem phpize enthalten ist, ist bei Dir offensichtlich nicht installiert. Suche mal nach einem Paket, das auf '-dev' endet, z.B. 'php-dev' oder ähnliches... Wenn das installiert ist, gibt's auch phpize. Bzw. ich sehe gerade, dass bei Debian das Paket 'php5-dev' heißt und das dann nicht 'phpize', sondern 'phpize5' heißt (die benennen das wohl auf Grund von Kompabilität mit PHP4 um).

                          Jo, das wird wohl doch 'ne längere Aktion.
                          Da werde ich mich die nächsten Tage nochmal ans Selberbauen machen auf der nächsten Platte.
                          Also alles nochmal von vorne. Irgendwann kann ich's dann hoffentlich auswendig.

                          Nun suche ich erstmal nach einem dev-Paket für die Fertiglösung
                          Soweit war ich vorhin schon einmal, hab dann aber abbrechen müssen :-(

                          Bis später bestimmt.
                          Mal schauen, wer dann noch hier ist.

                          Harzliche Grüße vom Berg
                          http://bergpost.annerschbarrich.de

                          Tom

                          --
                          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                          Nur selber lernen macht schlau
                          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

                          1. Hello,

                            Bis später bestimmt.
                            Mal schauen, wer dann noch hier ist.

                            ging jetzt schneller, als ich dachte.

                            Build complete.
                            (It is safe to ignore warnings about tempnam and tmpnam).

                            testserver:~/cvs/pecl/dio# make install
                            Installing shared extensions:     /usr/lib/php5/20060613+lfs/
                            testserver:~/cvs/pecl/dio#

                            Zwischendurch hat das "apt-get install php5-dev" noch das Postgre DBMS runtergeknallt. Mal sehen, ob es noch funktioniert...

                            Aber sonst sieht es jetzt gut aus.

                            Der Vollständigkeit halber:

                            in der php.ini das extension_dir setzen

                            ;;;;;;;;;;;;;;;;;;;;;;;;;
                            ; Paths and Directories ;
                            ;;;;;;;;;;;;;;;;;;;;;;;;;

                            ; UNIX: "/path1:/path2"
                            ;include_path = ".:/usr/share/php"
                            ;
                            ; Windows: "\path1;\path2"
                            ;include_path = ".;c:\php\includes"

                            ; The root of the PHP pages, used only if nonempty.
                            ; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
                            ; if you are running php as a CGI under any web server (other than IIS)
                            ; see documentation for security issues.  The alternate is to use the
                            ; cgi.force_redirect configuration below
                            doc_root =

                            ; The directory under which PHP opens the script using /~username used only
                            ; if nonempty.
                            user_dir =

                            ; Directory in which the loadable extensions (modules) reside.
                            ; extension_dir = "./"
                            extension_dir = /usr/lib/php5/20060613+lfs/

                            und die extension zum automatsichen laden anmelden

                            ;;;;;;;;;;;;;;;;;;;;;;
                            ; Dynamic Extensions ;
                            ;;;;;;;;;;;;;;;;;;;;;;
                            ;
                            ; If you wish to have an extension loaded automatically, use the following
                            ; syntax:
                            ;
                            ;   extension=modulename.extension
                            ;
                            ; For example, on Windows:
                            ;
                            ;   extension=msql.dll
                            ;
                            ; ... or under UNIX:
                            ;
                            ;   extension=msql.so

                            extension=dio.so

                            und da sind sie!

                            [316] => deg2rad
                                         [852] => dgettext
                             +-->        [1092] => dio_close
                             |           [1089] => dio_fcntl
                             |           [1085] => dio_open
                             |           [1090] => dio_read
                             |           [1088] => dio_seek
                             |           [1087] => dio_stat
                             |           [1093] => dio_tcsetattr
                             |           [1086] => dio_truncate
                             +-->        [1091] => dio_write
                                         [510] => dir
                                         [193] => dirname

                            Der Index davor stammt aus meiner Abfrage mit get_defined_functions
                            http://de2.php.net/manual/de/function.get-defined-functions.php

                            Nun noch ausprobieren, ob sie auch das tun, was sie sollen...

                            dann geb ich dreie aus. *freu*

                            Harzliche Grüße vom Berg
                            http://bergpost.annerschbarrich.de

                            Tom

                            --
                            Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                            Nur selber lernen macht schlau
                            Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

              2. Hello,

                (Ich kann es z.Zt. nur mit PHP4 ausprobieren, und das ist ja witzlos, denn da wurde
                definitv totzdem gewartet, auch wenn extra NonBlocking gewünscht wurde.)

                Sorry, aber das kann ich mir nicht vorstellen. Wie hast Du das denn getestet?

                Ich hatte das im Prinzip so:

                $fp = dio_open ('file.txt', O_RDWR | O_CREAT, 2666);
                                                               ----
                 $res = dio_fcntl ($fp, F_SETLK, array ('start' => 0, 'length' => 400, 'whence' => SEEK_SET, 'type' => F_WRLCK));

                Einen Fehler habe ich entdeckt, der Mode stand bei mir auf 2666, wie auch immer ich damals darauf gekommen bin. Ich weiß auch nicht mal mehr, was das sollte.

                Das hat aber nicht das fehlerhafte Verhalten ausgelöst.
                Ih habe es eben mit den alten Dateien und mit Deinen nochmals auf PHP 5.2.0 und auf dem alten System mit 4.3.8 ausprobiert. Vom Verhalten kein Unterschied.

                Meine Aufzeichnungen stammen aber noch von einem 4.2.x-System (?)
                Das kannte noch kein file_get_contents()

                Da hat es nicht funktioniert.
                Ich habe damals den vermeintlichen Bug an PHP gesendet und mir heiße Ohren eingehandelt, das müsse so sein. Kann sein, dass sie es daraufhin repariert haben.
                Ob ich allerdings DIE Platte auch noch irgendwo habe, weiß ich nicht.

                Für heute ist jedenfalls erstmal Schluss.

                Und, *oh Freude* es funktioniert zur Abwechslung mal alles. :-))

                Vielen Dank nochmal für Deine Unterstütung.

                Bald dürfte dem System nichts mehr fehlen.

                Harzliche Grüße vom Berg
                http://bergpost.annerschbarrich.de

                Tom

                --
                Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
                Nur selber lernen macht schlau
                Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      3. echo $begrüßung;

        Und _wenn_ die() hier jemals ausgeführt würde, wäre es nicht unbedingt geschickt, ein größeres Skript derartig abzubrechen. Es sollte dann eine qualifizierte Fehlerbehandlung stattfinden, die den User nicht in den Wald stellt.

        Ich wollte das Beispiel möglichst einfach halten, so dass wirklich nur der eigentliche Sachverhalt dargestellt wird - und bei diesen einfachen Beispielen, die nichts anderes tun, funktioniert die Fehlerbehandlung über die() zufriedenstellend.

        Für das Beispiel würde es meiner Meinung nach auch reichen, dass die Fehlerbehandlung nur angedeutet wird, z.B. mit einem Kommentar. Das Auswerten der Rückgabewerte, also das Reagieren auf Fehlerzustände ist vollkommen in Ordnung. Nur ist es leider in Beispielen üblich, die Behandlung mal eben fix mit die() auszuführen. Und ebenfalls üblich ist es, dass unbedarfte Anwender solche Beispiele nicht genügend reflektiert habend übernehmen. Das ist der Grund, warum ich solche die()-Beispiele nicht gutheiße (und Tom ja offensichtlich auch nicht).

        Wenn ich dort jetzt noch eine ausgereifte Fehlerbehandlung einbauen würde, dann würde ich das Beispiel nur unnötig verkomplizieren.

        Das halte ich auch nicht für erforderlich. Ein Beispiel soll zeigen, wie es geht, muss aber nicht unbedingt komplett copy'n'paste-ausführbar sein. (Meinetwegen könnten auch <?php, ?> und die Shebang-Zeilen wegbleiben.)

        Leider sind solche ja durchaus "funzenden" Beispiele geeignet, sich über den Weg des Copy & Paste beliebig oft zu vervielfältigen und sich dann als Standart (sic!) zu etablieren.
        Ich habe kein Problem damit, wenn sich der aktuelle Code als Standard etablieren würde, denn ich kann Deine Kritik nicht nachvollziehen (s.o.).

        Dass du mit dem Locking-Artikel die allgemeine Scripting-Qualität erhöhen möchtest, ist lobenswert und nicht zu kritisieren. Der Artikel wird sicher in Zukunft hier oft verlinkt werden (müssen). Nur gibst du hier nicht nur ein gutes Beispiel, wie man es besser machen kann, sondern mit dem Sterbenlassen im Fehlerfall auch ein gutes Beispiel wie man es nicht machen sollte. Gerade, wenn man als Vorbild gilt, sollte man auch solche Kollateralschadensquellen beachten (gelingt nicht immer, aber versuchen sollte man es stets).

        Du musst dich jetzt nicht unbedingt genötigt fühlen, die Beispiele umzuarbeiten. Es würde auch reichen, wenn du da Fußnoten hinzufügtest, die auf den (noch zu schre<I>benden) Artikel zu Fehleraufspürmöglichkeiten und zur fehlertoleranten Programmierung im Allgemeinen verwiesen. :-)

        echo "$verabschiedung $name";

        1. Hallo dedlfix,

          Ich werde mir Deine Anmerkungen mal in Ruhe durch den Kopf gehen lassen und mir überlegen ob ich was ändere bzw. was ich am Artikel ändern werde (was dann u.U. auch die anderen Sprachen betrifft).

          Viele Grüße,
          Christian

    2. Hello,

      Anmerkung zum PHP-Teil:

      if (!flock ($fp, LOCK_EX)) {
        die ('Sperren der Datei fehlgeschlagen!')};

      Ich habe das eben nochmals ausprobiert. (Aber Vorsicht, mein Debian ist anders als andere ... :-P)

      Die() wird im Leben nicht ausgeführt, wenn die Datei schon mit LOCK_SH oder LOCK_EX oder auch mit einem dio_lock geöffnet ist.

      Die übliche max_execution_time von 30 Sekunden ermittelt sich sicherlich wieder aus der verbrauchten Prozessorzeit des Skriptes. Da aber das flock() intern immer wieder auf ein "sleep" läuft, bevor es den nächsten Lockversuch vornimmt und sleep keine (kaum) Prozessorzeit verbraucht, dauert das Timeout ewig. Ich habe es in einer halben STUNDE nicht erreicht, obwohl 30 Sekunden eingestellt sind.

      Harzliche Grüße vom Berg
      http://bergpost.annerschbarrich.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      1. Hallo Tom,

        Die() wird im Leben nicht ausgeführt, wenn die Datei schon mit LOCK_SH oder LOCK_EX oder auch mit einem dio_lock geöffnet ist.

        Wenn ein anderes Programm das Lock hat: Nein, natürlich nicht, dafür brauche ich auch das die() nicht. (siehe mein anderes Posting)

        Die übliche max_execution_time von 30 Sekunden ermittelt sich sicherlich wieder aus der verbrauchten Prozessorzeit des Skriptes.

        Ja.

        Da aber das flock() intern immer wieder auf ein "sleep" läuft, bevor es den nächsten Lockversuch vornimmt

        Nein. Bei ALLEN Systemaufrufen legt sich der Prozess *GRUNDSÄTZLICH* schlafen - sleep() ist halt ein Systemaufruf, bei dem der Kernel auf X Sekunden wartet, flock() einer, bei dem der Kernel auf das Freiwerden der Sperre wartet, während read() ein Systemaufruf ist, bei dem der Kernel Daten holt (und evtl. auf diese wartet).

        Ich habe es in einer halben STUNDE nicht erreicht, obwohl 30 Sekunden eingestellt sind.

        Du wirst das Timeout NIE erreichen, weil solange flock() nicht zurückgekehrt ist, die Kontrolle NIE an den PHP-Prozess zurückgegeben wird - und damit der Zeitzähler NIE hochlaufen wird.

        Viele Grüße,
        Christian

        1. Hello,

          Du wirst das Timeout NIE erreichen, weil solange flock() nicht zurückgekehrt ist, die Kontrolle NIE an den PHP-Prozess zurückgegeben wird - und damit der Zeitzähler NIE hochlaufen wird.

          Danke.

          Harzliche Grüße vom Berg
          http://bergpost.annerschbarrich.de

          Tom

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)