Wie sperre ich eine Datei (locking)?

Inhalt:

Problem

Du hast einen Webcounter und möchtest den Inhalt um eins hochzählen. Der klassische Fehler ist, die Datei zu öffnen, den Inhalt auszulesen, die Datei wieder zu schließen, die Datei zum Schreiben öffnen und den neuen Wert einfügen. In der Zwischenzeit können beliebige Prozesse auf die Datei zugreifen.

Ein damit zusammenhängender Fehler ist es, die Datei beim zweiten mal auch noch mit open COUNT, '>', 'pfad' zu öffnen. Dabei wird der Inhalt zerstört, bevor der lock angelegt werden kann.

Lösung

# konstanten LOCK_EX, SEEK_SET importieren
use Fcntl qw(:seek :flock);

# dateiname
my $counter = "counter";

# Datei zum Lesen und Schreiben öffnen
open my $lock, '+<', $counter
   or die "Konnte '$counter' nicht öffnen: $!";

# exklusiv sperren
flock $lock, LOCK_EX;

# counter auslesen
chomp(my $num = <$lock>);

$num++;

# an den anfang der datei springen
seek $lock, 0, SEEK_SET;

# datei auf größe 0 zurücksetzen
truncate $lock, 0;

# neuen wert reinschreiben
print $lock "$num\n";

# schließen
close $lock;


# ---------- ohne kommentare

use Fcntl qw(:seek :flock);
my $counter = "counter";
open my $lock, '+<', $counter
   or die "Konnte '$counter' nicht öffnen: $!";
flock $lock, LOCK_EX;
chomp(my $num = <$lock>);
$num++;
seek $lock, 0, SEEK_SET;
truncate $lock, 0;
print $lock "$num\n";
close $lock;

Kurze Liste der Konstanten

LOCK_SH: Shared Lock

Wenn man nur lesen will

LOCK_EX: Exclusiver Lock

Wenn man schreiben (und lesen) will

LOCK_NB: Nicht blockierender Lock

Wird benutzt mit LOCK_SH oder LOCK_EX. Gibt sofort ein Ergebnis zurück, anstatt zu warten.
if (flock FILEHANDLE, LOCK_EX | LOCK_NB) {
 # prima
}
else {
 # kein lock, Plan B
}

LOCK_UN: Lock aufheben

Wird selten gebraucht, da ein Schließen der Daei den Lock automatisch und atomar aufhebt.

Literatur

perldoc -q locking

perldoc perlopentut

perldoc -f seek

perldoc -f truncate

Ergänzungen, Kommentare

Kommentare werden am besten in folgender Form vorgenommen, damit sie im Inhaltsverzeichnis angezeigt werden (natürlich ohne das <verbatim>):
---+++ Main.??? - 14 Jul 2003 - Betreff

UtilFaqSubForm edit

Titel Wie sperre ich eine Datei (locking)?
Autor TinaMueller
Bereich FaqEinUndAusgabe
Topic revision: r4 - 2005-11-21 - 21:10:12 - TinaMueller
 
Bitte die NutzungsBedingungen beachten.
Bei Vorschlägen, Anfragen oder Problemen mit dem PerlCommunityWiki bitten wir um WebBottomBarExample">Rückmeldung.