$xNeTworKx: Wie ist das jetzt genau mit flock?

Hallo,
Wenn Script A auf eine Datei zugreifen will und währendessen Script B auch darauf zugreift, sperrt dann Script A Script B solange bis Script A "fertig" ist, oder funktioniert flock nur für das selbe Script?
Ich hoffe ich habe es verständlich beschrieben.

$xNeTworKx.

--
Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
  1. Hallo $xNeTworKx,

    Wenn Script A auf eine Datei zugreifen will und währendessen Script B auch darauf zugreift, sperrt dann Script A Script B solange bis Script A "fertig" ist, oder funktioniert flock nur für das selbe Script?

    vorne weg: Der PERL Befehl flock greift, meines Wissens nach, auf eine Funktion der C-Library zurück. Die Speere kann somit auch für Prozesse gelten, die gar nichts mit PERL zu schaffen haben.
    Es gibt zwei wichtige Arten von flock:

    1. flock(FILE, LOCK_EX)
      Ein Script wartet solange bis es eine exclusive Spere für FILE erhält. Wenn die Spere erteilt ist kann kein anderer Prozess mehr lesend oder schreibend auf FILE zugreifen (natürlich nur falls der andere Prozess mit flock arbeitet).

    2. flock(FILE, LOCK_SH)
      LOCK_SH steht für shared lock. d.h. mehre Prozesse können gleichzeitig auf FILE lesend zugreifen. LOCK_SH stellt also sicher, daß FILE nicht während des lesens verändert wird.

    Wenn du in deinen Scripten nur lesend auf FILE zugreifst, würde ich auf jeden Fall (2) verwenden. Dann wird Script B nämlich nicht angehalten. Im Fall (1) hast du aber vollkommen recht.

    Genau genug?

    Grüße,

    Peter

    1. Hallo,
      ok alles klar, danke :)

      $xNeTworKx.

      --
      Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
    2. Hallo!

      vorne weg: Der PERL Befehl flock greift, meines Wissens nach, auf eine Funktion der C-Library zurück. Die Speere kann somit auch für Prozesse gelten, die gar nichts mit PERL zu schaffen haben.
      Es gibt zwei wichtige Arten von flock:

      1. flock(FILE, LOCK_EX)
        Ein Script wartet solange bis es eine exclusive Spere für FILE erhält. Wenn die Spere erteilt ist kann kein anderer Prozess mehr lesend oder schreibend auf FILE zugreifen (natürlich nur falls der andere Prozess mit flock arbeitet).

      2. flock(FILE, LOCK_SH)
        LOCK_SH steht für shared lock. d.h. mehre Prozesse können gleichzeitig auf FILE lesend zugreifen. LOCK_SH stellt also sicher, daß FILE nicht während des lesens verändert wird.

      Dazu habe ich mal eine Frage. Irgendwann brauchte ich mal einen sehr sicheren Counter, der es nicht zulassen durfte das 2 mal dieselbe Zahl gelesen werden darf.

      Es ging um ein Script, welches sich aus einer txt-Datei eine Zahl eingelesen hat, diese um 1 erhöht hat und die neue Zahl wieder zurückgeschreiben hat.

      also sowas

      fopen(FILE)
      $data = fread()
      fputs($data++)
      fclose()

      etwas vereinfacht.

      Das habe ich probiert mit einem flock sicher zumachen:
      fopen(FILE)
      flock(LOCK_EX)
      $data = fread()
      fputs($data++)
      fclose()

      Nur wenn jetzt 2 User (fast) gleichzeitig drauf zugreifen, könnte es doch passieren dass der erste User die Datei öffnet, und bevor er die Datei sperrt liest der 2. User die Datei ein, oder? Oder kann sowas definitiv nicht passieren?

      Grüße
      Andreas

      1. Hallo Andreas,

        Es ging um ein Script, welches sich aus einer txt-Datei eine Zahl eingelesen hat, diese um 1 erhöht hat und die neue Zahl wieder zurückgeschreiben hat.

        Das habe ich probiert mit einem flock sicher zumachen:
        fopen(FILE)
        flock(LOCK_EX)
        $data = fread()
        fputs($data++)
        fclose()

        Nur wenn jetzt 2 User (fast) gleichzeitig drauf zugreifen, könnte es doch passieren dass der erste User die Datei öffnet, und bevor er die Datei sperrt liest der 2. User die Datei ein, oder? Oder kann sowas definitiv nicht passieren?

        Gute Frage, denn der Fall ist gar nicht so theoretisch: Es ist ja möglich, daß die CPU Zeit des ersten Scripts gerade zwischen open und flock verbraucht ist. Erst in der nächsten Systemrunde kann der Prozess dann weiterarbeiten und inzwischen ist Prozess 2 an der Reihe.

        Damit flock anständig funktioniert, sollten aber immer _alle_ beteiligten Programme flock verwenden. Der zweite Prozess wird also die Datei öffnen und ein eigenen lock verlangen. Dann gibt es zwei Möglichkeiten:
        Prozess 1 ist wieder am Zug und erhält den lock, Prozess 2 wird angehalten bis 1 die Sperre wieder freigibt.
        Zweite Möglichkeit: Prozess 2 erhält den lock und 1 muss warten.

        Möglichkeit zwei ist dein Fall. Der 2 Prozess wird also tatsächlich die Datei erst auslesen/bearbeiten - Das ist aber nicht wirklich schlimm, da Prozess 1 die Datei (er wartet ja auf seinen exclusiven lock) nicht währenddessen verändern kann.
        Und falls Prozess 2 die Datei verändert, liest Prozess 1, wenn er weitermachen darf, eben die veränderte Datei aus (open liefert ja - vereinfacht gesagt - nicht eine ganze Datei sondern nur einen Zeiger auf den Speicher zurück und hier steht halt jetzt etwas neues.)

        Grüße,

        Peter

        p.s.: Oh je, jetzt habe ich mich doch mit einem PHP Problem befasst - !@#$*.  ;-)

        1. Hi Peter!

          Vielen Dank für die Erklärung, jetzt hab ichs verstanden und weiß es einzusetzen!

          p.s.: Oh je, jetzt habe ich mich doch mit einem PHP Problem befasst - !@#$*.  ;-)

          Das war doch kein PHP, nur ein bisschen von PHP angehaucht, aber vermutlich auf andere Sprachen übertragbar ;-)

          Grüße
          Andreas

      2. fopen(FILE)
        $data = fread()
        fputs($data++)
        fclose()

        etwas vereinfacht.

        Das habe ich probiert mit einem flock sicher zumachen:
        fopen(FILE)
        flock(LOCK_EX)
        $data = fread()
        fputs($data++)
        fclose()

        Nur wenn jetzt 2 User (fast) gleichzeitig drauf zugreifen, könnte es doch passieren dass der erste User die Datei öffnet, und bevor er die Datei sperrt liest der 2. User die Datei ein, oder? Oder kann sowas definitiv nicht passieren?

        Genau das wird irgendwann passieren.
        Wenn du in EINEM Skript eine Datei änderst und du wünscht nicht, das ein anderer Prozess die Datei in der Zwischenzeit verändert, musst du den flock während des ganzen Prozesses aufrecht erhalten.

        In deinem obigen Beispiel einfach, in dem du die Datei zum lesen und schreiben öffnest.

        my $file = "datei.txt";
        open F, "+<$file" || die "Kann $file nicht öffnen weil: $!";
        flock FILE, LOCK_EX;
        my $data = <FILE>;
        truncate FILE,0;
        seek FILE, 0, SEEK_SET;
        $data++;
        print FILE $data;
        close FILE;

        Nur so bist du auf der sicheren Seite.

        Struppi.

        1. Oder noch besser die antwort in der Perlfaq:

          -- zitat start --
          I still don't get locking. I just want to increment the number in the file. How can I do this?

          Didn't anyone ever tell you web-page hit counters were useless? They don't count number of hits, they're a waste of time, and they serve only to stroke the writer's vanity. Better to pick a random number. It's more realistic.

          Anyway, this is what you can do if you can't help yourself.

          use Fcntl ':flock';
          sysopen(FH, "numfile", O_RDWR|O_CREAT) or die "can't open numfile: $!";
          flock(FH, LOCK_EX) or die "can't flock numfile: $!";
          $num = <FH> || 0;
          seek(FH, 0, 0) or die "can't rewind numfile: $!";
          truncate(FH, 0) or die "can't truncate numfile: $!";
          (print FH $num+1, "\n") or die "can't write numfile: $!";

          Perl as of 5.004 automatically flushes before unlocking

          flock(FH, LOCK_UN) or die "can't flock numfile: $!";
          close FH or die "can't close numfile: $!";

          Here's a much better web-page hit counter:
          $hits = int( (time() - 850_000_000) / rand(1_000) );
          If the count doesn't impress your friends, then the code might. :-)

          -- zitat Ende --

          struppi.

    3. Moin,

      Es gibt zwei wichtige Arten von flock:

      1. flock(FILE, LOCK_EX) Ein Script wartet solange bis es eine exclusive Spere für FILE erhält. Wenn die Spere erteilt ist kann kein anderer Prozess mehr lesend oder schreibend auf FILE zugreifen (natürlich nur falls der andere Prozess mit flock arbeitet).

      2. flock(FILE, LOCK_SH) LOCK_SH steht für shared lock. d.h. mehre Prozesse können gleichzeitig auf FILE lesend zugreifen. LOCK_SH stellt also sicher, daß FILE nicht während des lesens verändert wird.

      Zu welcher Art flock gehört dann diese version?

      flock(logins,2) if ($doflocks); .......blabla flock(logins,8) if ($doflocks);

      Grüsse vom Alain

      --
      ...nobody is perfect I am nobody
      1. Hallo!

        Zu welcher Art flock gehört dann diese version?

        flock(logins,2) if ($doflocks);
        .......blabla
        flock(logins,8) if ($doflocks);

        Siehe http://www.php3.de/manual/de/function.flock.php

        Grüße
        Andreas

  2. Hi,

    Lustigerweise wollte ich auch gerade einen Thread zu dem Thema aufmachen ;-).
    So, jetzt aber meine Frage:
    Wie kann ich für flock eine Zeitbeschränkung definieren? Wenn mein Programm nämlich länger als z.B. zwei Sekunden auf die "Genehmigung" des flocks warten muss, soll dies einen Fehler ausgeben.
    Zuerst dachte ich, ich könnte einfach den Rückgabecode von flock auswerten, aber der ist logischerweise immer 1, da flock so lange wartet, bis die Datei wieder frei ist?

    mfg Andres Freund

    1. Hallo,

      Wie kann ich für flock eine Zeitbeschränkung definieren? Wenn mein Programm nämlich länger als z.B. zwei Sekunden auf die "Genehmigung" des flocks warten muss, soll dies einen Fehler ausgeben.

      perldoc -f alarm

      Viele Grüße,

      Stefan

      1. Hi,

        Wie kann ich für flock eine Zeitbeschränkung definieren? Wenn mein Programm nämlich länger als z.B. zwei Sekunden auf die "Genehmigung" des flocks warten muss, soll dies einen Fehler ausgeben.

        perldoc -f alarm

        Vielen, Dank, wie sehr kann man eigentlich auf der Leitung sitzen? Gibt es dagegen eigentlcih ein Mittel *g*?

        mfg Andres Freund