flock()を使った強固な排他処理(ファイルロック)
perlで排他処理(ファイルロック)を行う場合様々な方法があります。
昔のレンタルサーバの場合はflock()が使えない環境などがあり、
symlinkやmkdirを使った処理が多くありました。
しかし、スピード・信頼性に優れていて、現代どこのサーバ(Unix系の)でも使えるであろうflockを使わない手はないと思います。
flockなんか壊れる、信頼しない…使い方は間違っていませんか?
まずは各ロック方式の特徴を
■ symlink
・遅い。
・ロックしたままの状態(ロック用シンボリックリンク)が残る可能性がある。
・サーバーによっては使えない場合がある。
■ mkdir
・遅い。
・ロックしたままの状態(ロック用ディレクトリ)が残る可能性がある。
・処理全体をロックする場合に便利。
・どの環境でも使用できる。
■ flock
・速い。
・アンロックし忘れが無い。
■サンプルソース
flockは完了するまで永遠と処理を待ち続けるため10秒のアラーム処理を入れ10秒以内に完了しなければタイムアウトとしました。
この処理は強力でまずファイルが壊れる事はありません。
このファイルロックを使い、10万PV/日でも壊れませんでした。
ただし、ロック処理の間に他のファイルを開く時にはファイルハンドル(サンプルでは"FILEHANDLE")を変える必要があります。
これを怠ると必ずファイルが壊れます。
#ロック処理開始 eval { local $SIG{ALRM} = sub { die "timeout" }; alarm 10;#アラームを10秒に設定 #ログ読み込み&ロック open(FILEHANDLE,"+<"); #読み書きモードでファイルオープン flock(FILEHANDLE, 2); #ロック確認 ロック @data = <FILEHANDLE>; #@dataに読み込み alarm 0; }; alarm 0;#アラーム解除 if($@) {&error;}; # タイムアウト時の処理 別にsub errorが必要になる #〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 # ここにロック中に行う処理 #〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 seek(FILEHANDLE, 0, 0); # ファイルポインタを先頭にセット print FILEHANDLE @data; # ファイルに書き込む truncate(FILEHANDLE, tell(FILEHANDLE)); # ファイルサイズを書き込んだサイズにする close (FILEHANDLE); #closeで自動にロック解除
-
前の記事
記事がありません
-
次の記事
改行コードの変換 2006.10.31