ファイルのlockについて

flcokについて

flockってファイルハンドルを開いた後にチェックする印みたいなもんだった。
つまりはflockの戻り値でlock中かどうかの判断をするみたい。あってんかな??
詳しくはここを見てください。

  • flock(FH, 1) 読込中なので書込をロック、あとから来たら待つ。(ブロック)
  • flock(FH, 2) 書込中だから書込読込ロック、あとから来たら待つ。(ブロック)
  • flock(FH, 5) 読込中なので書込をロック、あとから来たら0を返す。
  • flock(FH, 6) 書込中だから書込読込ロック、あとから来たら0を返す。
  • flock(FH, 8) ロック解除(close(FH)すれば解除なのであまり使わない)。

上記のサイトより引用

この実装だとファイルハンドルは必ず開けないといけないので
書込時は正常にロックされるが読込中は上書きしないようにしようとしても

open my $fh, ">", filename or die $!;

こんな感じでファイルハンドルを開けないといけないので
既存のデータがなくなっちゃう自体におちいった。
まぁ当然ちゃ当然だけどw
で、色々試してできたんでメモ代わりに書いておく。

読込時のロック

  • read_lock1.pl
#!/usr/bin/perl

use strict;
use warnings;

my $op = open my $fh, '<', 'test.txt' or die $!;
my $lock = flock $fh, 5;
print "read_lock[$op:$lock]";
print join "", <$fh>;
close $fh;
  • write_lock1.pl
#!/usr/bin/perl -l

use strict;
use warnings;

my $op = open my $fh, ">", 'test.txt' or die $!;
my $lock = flock $fh, 6;   #第二引数を"2"にするとcloseされるまでread_lock1.plの読み込みを待たせる。
print "write_lock[$op:$lock]";
print $fh 'orzorzorzorz';
sleep 5;         #この間に read_lock1.pl-read_lock1.plを実行
close $fh;

これを試すとわかるけど
書込中はread_lock.plの$lockの値は0を返す。
書込が終わると$lockの値は1を返す。
あとは$lockの値をみてコードかけばおk。

書込時のロック

こっちは書込時に比べて少し違うやり方をした。

  • read_lock2.pl
#!/usr/bin/perl

use strict;
use warnings;

my $op = open my $fh, '<', 'test.txt' or die $!;
my $lock = flock $fh, 5;    #第二引数を"1"にするとcloseされるまでread_lock1.plの読み込みを待たせる。
print "read_lock[$op:$lock]";
sleep 5;
print join "", <$fh> if $lock;
close $fh;
  • write_lock2.pl
#!/usr/bin/perl

use strict;
use warnings;

my $op = open my $fh, ">>", 'test.txt' or die $!;
my $lock = flock $fh, 6;
print "write_lock[$op:$lock]";

if ($lock){
    truncate $fh, 0;   # ファイルサイズを0バイトにする
    seek $fh, 0, 0;    # ファイルポインタを先頭にセット
    print $fh 'orzorzorzorz';
}
close $fh;


ちょっとゴリ押感はあるけどこれでできた。ってかモジュールありそうなのになぁ〜
やっぱlockファイルを作るので十分だからかな??あれば便利そうなのになー


IO::LockedFile
モジュールあればいいと思ったらあった。
これどうなんだろ。実装はflock使ってしてるっぽいけど・・・