Perlによるファイルの排他制御
Perlによる排他制御のサンプルです。
うわ、長い・・・と感じるかも知れませんが、ほとんどがコメントです。
alarm関数はウォーターフォール(純粋に上から下へ流れる考え方)にはそぐわないかも知れませんが、難しくありません。
私も食わず嫌いをしていた時期もあり、排他制御が決して難しくない事を知って頂くため、知識を共有します。
2009/7/3追記
alarm(0)書くところ間違えてました。
evalの中だけ書いてちゃイカンだろ・・・
私もまだ勉強不足です、皆様からのご教示をお待ちしております。
#!D:/usr/local/Perl/bin/Perl.exe print "◆ファイルを排他制御します。\n"; eval{ # Alarmシグナルキャッチ時、dieする $SIG{ALRM} = sub { die "timeout"; }; # 前のプロセスの終了〜ファイル書き込みに、5秒間だけ待つ # 一連の処理が5秒間以内に終わらないとタイムアウトします。 alarm(5); # ファイルを読み書きモードで開く # test.txtがないとエラーになります。 if(! open(out, "+< D:/test.txt")){ die "fileopen"; } print "ファイル開きました(5秒間でタイムアウト)。\n"; # ファイルロック if(! flock(out, 2)){ die "filelock"; } print "ファイルをロックしました。\n"; # もしテストするとしたら、ここで無限ループ # 以下は無限ループのサンプルです。 #while(){;} # ファイルの先頭を指定 if(! seek(out, 0, 0)){ die "fileseek"; } # ファイル書き込み if(! print out "ファイルへ書き込みます。\n"){ die "fileprint"; } print "ファイルに書き込んでいます。\n"; # ファイルサイズの変更 if(! truncate(out, tell(out))){ die "filetruncate"; } # ファイルをクローズ # ファイルをクローズすると自動的にロックも解除されます。 close(out); print "ファイルをクローズしました。\n"; # Alarmを初期化 alarm(0); }; # Alarmを初期化 (dieで抜けた時のため) alarm(0); if($@ =~ /timeout/){ print "ファイル書き込みがタイムアウトしました。\n"; }elsif($@ =~ /fileopen/){ print "ファイルを開けませんでした。\n"; }elsif($@ =~ /filelock/){ print "ファイルロックに失敗しました。\n"; }elsif($@ =~ /fileseek/){ print "ファイルの先頭を指定できませんでした。\n"; }elsif($@ =~ /fileprint/){ print "ファイルの書き込みに失敗しました。\n"; }elsif($@ =~ /filetruncate/){ print "ファイルサイズの変更に失敗しました。\n"; }elsif($@){ print "その他のエラーです。[".$@."]\n"; } if($@){ exit(1); } print "おしまい\n"; exit(0);