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);