# # ロックファイル # sub data_save { local($tmpfile) = $datafile; $tmpfile =~ s/(\w+)\.\w+$/$1\.tmp/i; #他のプロセスのロック状態をチェック foreach (1 .. 10) { #1秒に1回監視し、テンポラリーがなくなれば抜出する unless (-f $tmpfile) { $tmpflag = 1; last; } $tmpflag = 0; #テンポラリーが有れば他のプロセスがロック中 sleep(1); } #10秒間トライしても駄目ならリクエストをキャンセル if ($tmpflag == 1) { #perlのプロセス番号のテンポラリーを作成 $tmp_dummy = "$$\.tmp"; open(TMP,">$tmp_dummy") || die "Can't create tmp file.\n"; close(TMP); #パーミッションを変更 chmod 0666,$tmp_dummy; #プロセステンポラリーファイルへデータを書込む #別々のファイルに書き込むので衝突する可能性は0に等しい open(TMP,">$tmp_dummy") || die "Can't open tmp file.\n"; print TMP @DATA; close(TMP); #リネームするタイミングを計る #ロックされていなければロックする foreach (1 .. 10) { if (link($tmp_dummy,$tmpfile) == 1) { #ハードリンクに成功すればリネームしてロックを解除 chmod 0666,$datafile; rename($tmpfile,$datafile); chmod 0644,$datafile; last; } sleep(1); } unlink $tmp_dummy; #プロセステンポラリーを削除する } }