Thread open-Anweisung
(22 answers)
Opened by geloescht at 2012-06-24 00:30
Hier zwei kommentierte Funktionen zum nutzen von geschützten Zählern:
Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 # das Modul enthält Funktionen und Werte, # die man Braucht um Dateien zu Manipulieren. # Speziell brauchen wir hier "LOCK_EX" und "LOCK_UN" # ':flock' ist ein Befehl an das Modul # und macht diese Werte Verfügbar. use Fcntl ':flock'; # Funktion zum lesen des Zählerwerts sub read_counter { # Dateiname des Zählers muss übergeben werden my $file = shift( @_ ); # hier drin wird der Counterwert gespeichert # "undef" bedeutet das der wert zur zeit nicht definiert ist # testet man das mit "defined($counter)" so ist das False my $counter = undef; # wenn das lesend öffnen der Datei erfolgreich war. # open liefert "true" zurück wenn das öffnen ein Erfolg war. if( open(my $fh, '<', $file) ) { # Die Datei wird exklusiv gesperrt. # das funktioniert nur wenn alle Programme, # die auf die Datei zugreifen, das machen. # Perl fragt hier alle anderen Prozesse, # die auf diese Datei zugreifen, # ob einer sie schon gesperrt hat. # Wenn dem so ist wartet Perl solange bis die Sperrung aufgehoben wurde. # danach beansprucht Perl die Datei für diesen Prozess. flock($fh, LOCK_EX); # den Wert in der Datei lesen $counter=<$fh>; # sperrung aufheben, damit andere die Datei nutzen können flock($fh, LOCK_UN); # Datei Schließen close($fh); } # es wird der aktuelle Counterwert zurück gegeben return $counter; } # diese Funktion öffnet die Datei, # ließt den Zählerwert und erhöht ihn um 1 sub incement_counter { # Pfad zur Datei muss genannt werden my $file = shift( @_ ); # der Zähler wird erst mal auf "undef" gesetzt my $counter = undef; # Das FileHandle, welches zum lesen/schreiben # der Zählerwerte benutzt werden soll # # Es ist eine Vereinbarung das Filehandles, # die keinen speziellen Namen brauchen, # als "$fh" oder "FH" benannt werden. # das macht es anderen Lesern einfacher zu erkennen was gemeint ist # # seit Perl5 ist es möglich Dateihandles auch in Variablen zu packen # damit lassen sie sich auch in Arrays etc. nutzen # als interessanter Nebeneffekt wird das Filehandle automatisch geschlossen, # wenn die Variable gelöscht wird. # Scripte werden damit weniger Fehleranfälliger. my $fh=undef; # Wenn die Datei Existiert if(-f $file) { # wenn das Öffnen zum lesen und schreiben erfolgreich war if( open($fh, '+<', $file ) ) { # Die Datei Sperren flock( $fh, LOCK_EX ); # den aktuellen Wert lesen $counter=<$fh>; # Den Lese und Schreib-Punkt an den Anfang der Datei setzen # jedes Filehandle hat einen Zeiger der anzeigt, # wo in der Datei die nächsten Daten gelesen werden soll. # dieser Befehl besagt: vom Anfang der Datei aus gesehen # setze den Zeiger auf 0 seek( $fh, 0, 0 ); # die Größe der Datei auf 0 setzen # damit wird der Inhalt der Datei gelöscht truncate( $fh, 0 ); } } # die Datei existiert nicht else { # wenn die Datei schreibend geöffnet werden kann. if( open( $fh, '>', $file ) ) { # Die Datei sperren flock( $fh, LOCK_EX ); # den Zähler auf -1 setzen $counter = -1; } } # wenn $fh einen Wert enthält, # dann konnte die Datei geöffnet werden if( $fh ) { #den zähler um 1 erhöhen $counter++; # neuen wert in die Datei schreiben print $fh $counter; # Sperrung aufheben flock( $fh, LOCK_UN ); # Datei schließen close( $fh ); } # es wird der aktuelle Counterwert zurück gegeben return $counter; } Beispielanwendung: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 my $counter_file='counter.txt' my $cnt=read_counter($counter_file); # wenn das lesen nicht erfolgreich war # wird von read_counter "undef" in $cnt geschrieben # wenn man das testet, # kann man heraus finden, # ob das lesen erfolgreich war. # die Fehlermeldung der letzten Dateiaktion # steht in der Spezialvariable: "$!" die("Konnte Zähler nicht lesen $!\n") unless( defined ( $cnt ) ); print "COUNTER: $cnt\n"; $cnt=incement_counter($counter_file); die("Konnte Zähler nicht lesen $!\n") unless( defined ( $cnt ) ); print "COUNTER: $cnt\n"; Edit: Einen Fehler im Open-Modus korrigiert es heißt "+<" und nicht "<+" das kann ich mir nie merken. :-/ Last edited: 2012-06-24 01:47:58 +0200 (CEST) |