flockの基本的な使い方

[上に] [前に] [次に]
シロ 1999/11/28(日) 01:17:20
perlのflock()関数について、
ラウンジの過去ログ等を読んで勉強したのですが、
どうも基本的なところが理解できません。
例えば、1つのデータファイルに対して、
書き込み・読み込み・書き換えの処理を行う場合、
それを3つのスクリプトに分けて書いても、
それぞれの処理でflockを使っていれば
きちんとロックされるのでしょうか?
また、データファイルにロックをかけるかわりに
ロック用のファイルを使って
flockでロックをかける場合は、
読み込みロック・書き込みロック
(↑データファイルに対する読み書き)を
使い分ける方法はないでしょうか。
わかりにくい質問で申し訳ありません。

シロ 1999/11/28(日) 01:39:22
もう1つ、お聞きしたいのですが・・
flockやその他のperlでの排他処理について
詳しく解説しているサイトがありましたら教えてください。
自分では検索しても見つけられませんでした。
よろしくお願いいたします。

seea 1999/11/28(日) 23:28:18
すべてのスクリプトで、処理が行われる直前に
flock(FH, 2);
などとして排他的ロックを行えば、概ねOKです。
使い分けに関しては、わかりませんが
あまりロック処理に凝って複雑なスクリプトにしても、
安全性が飛躍的に高まることは、ないと思います。

もっとべつの観点、たとえば、スクリプト自体を最適化して
処理時間(CPU占有時間)を短縮させることで、ファイル破損の
確率を減少させるという方法もあります。
(私は、この考え方でスクリプトを記述しています)

まあ、どんなに優れたスクリプトでも、壊れるときは
壊れますが。(ディスクエラー、サーバーダウン、人為ミス
トラブルの元は、いくらでもあります)

ジェンウェイ大佐 [E-Mail] 1999/11/29(月) 00:13:53
一般的な掲示板の書き込み処理ですと

−例1

 open(LOG,"$file");
 @line = <LOG>
 close(LOG);

 〜配列処理〜

 open(LOG,">$file");
 print LOG "@line";
 close(LOG);


ファイルを読み出して閉じ、処理後もう一度ファイルを開いてログに書き出しという風にしていると思います。
これではファイルを読み出して書き込み処理の隙間に割り込まれると、割り込まれた方の書き込みが飛んだり、
書き出しの最中に割り込まれるとログが飛びます。ですから私流のロック方法(といってもこちらの過去ログで勉強さしてもらった方法ですが、)

−例2

 open(LOG,"+< $file");
 flock(LOG, 2);
 @line = <LOG>

 〜配列処理〜

 truncate(LOG, 0);
 seek(LOG, 0, 0);
 print LOG "@line";
 close(LOG);


という操作が一番固いロック方法だと思います。
ちなみに一番上の例にそのままflockを書き加えて

−例3

 open(LOG,"$file");
 flock(LOG, 1);
 @line = <LOG>
 close(LOG);

 〜配列処理〜

 open(LOG,">$file");
 flock(LOG, 2);
 print LOG "@line";
 close(LOG);


という処理方法ですと処理の間に割り込まれたらアウトです。
また、

 open(LOG,">$file");
 flock(LOG, 2);

だとopenとflockの間にもスキがあります。(open(LOG,">$file");の時点でログがゼロクリアされるので)
例3の書き込み処理を

 open(LOG,"+< $file");
 flock(LOG, 2);
 truncate(LOG, 0);
 seek(LOG, 0, 0);
 print LOG "@line";
 close(LOG);

とすれば書き出し時のロックはされますが、読み出し→書き出しの間のスキは残っていますから例2が一番良い方法でしょう。
ちなみに例2の方法を自分のサイトのWebチャットに使っていますが、最高で約15人の参加者で使ってもログが飛んだことは
無いです。(FreeBSD3.2R + OCNエコノミーの自前サーバにて)

これが参考になるかどうか分かりませんが、お役に立てれば光栄です。

シロ 1999/12/04(土) 14:47:41
解決チェックが遅れて申し訳ありません。
いただいた回答とラウンジの過去ログを参考に、
スクリプトを書いてみたいと思います。
seeaさん、ジェンウェイ大佐さん、
どうもありがとうございました。

シロ 1999/12/04(土) 14:48:16
[[解決]]
とか言ってチェック忘れてました…。

[上に] [前に] [次に]