Andreas Korthaus: file-locking um konkurrierende Datei-Zugriffe zu regeln?

Beitrag lesen

Hi Tom!

Doch das geht auch mit PHP. Lies Dir nochmal meine Antwort oben durch

hab ich ;-)

Das geht nur, wenn alle Prozesse dieselben Regeln berücksichtigen, am besten dasselbe "API-Script". Sonst benötigt man mandatory Locking.

Ja, das könnte man ja sicherstellen. "mandatory Locking" kann PHP ja nicht.

Wie würdest Du das jetzt implementieren, das heißt sicherstellen dass es keine doppelten IDs gibt (was ja passiert wenn die Datei mit der aktuellen ID von einem 2. Prozessen zw. fopen() und flock() aufgerufen wird )?

Das habe ich oben schon beschrieben:

Datei öffnen Handle besorgen
  Exclusive Lock beantragen

Zähler auslesen
  Zähler incrementieren und merken
  Zähler zurückschreiben

Ja, aber wie mache ich das mit einem handle? Meinst Du hier das handle welches LOCK "beantragt" hat?

$fp = fopen ('test.txt','a+');
$id = fread($fp,32);
fseek($fp,0,SEEK_SET);
fputs($fp, ++$id);

Geht nicht.

Wenn ich die neue ID zurückschreiben will, muss ich den lock lösen, das handle schließen, und ein neues besorgen und erneut locken. Dazwichen kann ne Menge passieren. Oder gibt es da doch eine Möglichkeit mit nur einem handle? Bedenke dass ich z.B. 123 auslese, und am Ende soll 124 drin stehen.

Datei schließen

Schlüssel zurückliefern

Außer, dass da unerwünschte Dateioperationen (rm, chmod, mv) oder ein Connection Loss stattfinden können, kann nichts schlimmes passieren. Und dass diese Veränderungen nicht stattfinden, dafür muss man sorgen und für den Fall dass doch, immer die Fehler abfragen.

Ja, das ist nicht das Problem.

Eine externe Lock-Datei hat IMHO gerade bei besonders vielen Zugriffen den Nachteil, dass es zu einem Dead-Lock kommen kann, falls ein Prozess stirbt...

Wenn ein Prozess stirbt, gibt PHP automatisch die Handles zurück und das OS löst automatisch die Locks wieder auf.

ich dachte dran, eine extra Datei anzulegen, und immer wenn diese Datei vorhanden ist, dann gilt die Datendatei als gesperrt. Wenn aber ein PHP-Prozess stirbt ohne dieses Datei gelöscht zu haben, ist das Mist, würde ich also nicht machen sowas.

Die einzige sichere Möglichkeit die mir gerade wieder eingefallen ist funktioniert so:

$lf = 'LOCK';     // Lock-Datei (leer)
  $cf = 'counter';  // Counter-Datei (enthält ID)

// externes LOCK-File sperren
  $lp = fopen($lf,'r');
  flock($lp,LOCK_EX);

// eigentliche counter-Operation durchführen
  $fp = fopen($cf,'r');
  $id = fread($fp,32);
  fclose($fp);
  $fp = fopen($cf,'w');
  fputs($fp,++$id);
  fclose($fp);

// externes LOCK-File entsperren
  flock($lp,LOCK_UN)
  fclose($lp);

wenn sich alle hieran halten sollte der counter 100% konsistent funktionieren.

Grüße
Andreas

--
SELFHTML Linkverzeichnis: http://aktuell.de.selfhtml.org/links/