flockの入れ方は、これでいいのでしょうか?

[上に] [前に] [次に]
がんま [E-Mail] 1998/08/30(日) 00:00:48
一つのファイルに2人が同時に書込む場合が想定されるので
「flock」なるものが必要と書籍にあったので、入れようと思ったのですが
ちょっとよく判らないので、質問させていただきます。

open(OUT, '>./list.dat');
foreach ( sort @datas ) {
print OUT "$_\n";
}
close(OUT);

この書き方は、この前教わったのを、そのまま使ってしまったものですが
私の判断ではこの中に「flock」を付けるものと・・・違うのかな?

だから、ちょっと間の抜けた書き方をしているとは思いますが

open(OUT, '>./list.dat');
flock(???,2);
foreach ( sort @datas ) {
print OUT "$_\n";
flock(???,8);
}
close(OUT);

と、こうなるのでは? と思っているのです。
「???」は、書籍では「TXT」となっているのですが、正直言って
この辺の区別が、まだ出来ていないので、こう表記しました(^^;

ファイルロックの書式で、お分かりの方がいましたら
よろしくお願いします。

B-Cus 1998/08/30(日) 02:46:54
上の検索で「flock」をキーワードとして探せば結構出てきます
ので、まずそれを参考にしてください。また、こちらに
まとめてあるものも読むといいでしょう。
 http://www.cup.com/negi/tips/flock.html


しかし、ファイルを更新されるつもりなら

1. データ読み込み
2. データ更新
3. データ書き込み

という手順になりますが、3のときだけロックかけても
うまくいかないのはわかりますでしょうか?

こういう場合は、1の前にロックをかけて、3の後でロック
解除というのがいいと思います。この場合はロックファイルを
別に使うことになりますね。

あとflock以外にも、シンボリックリンクとかmkdirを使って
排他制御できます。

Tiot [E-Mail] 1998/08/30(日) 02:56:00
ファイルの書き込みをおこなうような
スクリプトの場合はファイルのロックをしたほうがいいと思います。
そうでないと、たまたま、リクエストが重なったときなどに
空のファイルが上書きされてしまい、
以前のログが消えてしまうなどということがあります。
−掲示板のログとかは、ファイルロックなどをほどこした上で
−バックアップをとるのがいいと思います。

実際のファイルロックの書式はがんまさんの書いた書式の
???部分にファイルハンドラ(ここではOUT)を入れればいいと思います。
#ファイルハンドラというのは
#open(OUT, '>./list.dat'); の式の第一引数(括弧の中のカンマで区切られた
#一つ目の要素)にあたるものです。
#以後のスクリプトの中では./list.datはこのファイルハンドラで扱われます。
#close(OUT); といったら、./list.datを閉じることになります。
#同様にflock(OUT,2);は./list.datをロック、
#flock(OUT,8);は./list.datのロックを解除、です。

sub lock {
    local(*XXX) = @_;
    eval("flock(XXX, 2)");
    if ($@) {
        return 0;
    }
    return 1;
}

上のようなサブルーチンを使って(XXXはファイルハンドラ)
ファイルのロックをすることもあります(アンロックも同様)。
これだと、ファイルロックの際のエラートラップが行えます。
ファイルロックがうまくいかなかった際に、
エラーメッセージを出すなど。

ほかにも、いろいろな方法があるようです。
エラートラップは奥が深いです。
私もよくわかってません。
プロが書いたスクリプトをみるとこういうところが違うなぁと、
感心することがよくあります。

ただ、以前、興味があって、どれくらいのタイミングで
リクエストを出したらログが消えるなどのトラブルが起きるか
実験してみたことがあるのですが、
その際は何度か試してみても、そういったトラブルは起こらなかったです。
ファイルのロックをしないスクリプトで
3台のマシンのブラウザからリクエストを出してみたのですが。
プログラムの使用頻度や種類にもよるのでしょうが、
極端に神経質になる必要はないということでしょうか。
でも、一通りのファイルロックはほどこしたほうがよいと思います。

B-Cus 1998/08/30(日) 02:58:59
ところでどなたかNFS環境下でflockを使うとどうなるのか
教えてください。全くflockが効かないんでしょうか。
それともたまに失敗するんでしょうか。

Tiot [E-Mail] 1998/08/30(日) 03:07:37
B-Cusさんの書き込みとかぶってしまいました。
B-Cusさんが参考にあげてらっしゃる
http://www.cup.com/negi/tips/flock.html を見ればflockの書式は
大体わかりますね。
そこからリンクのあった
http://www2q.meshnet.or.jp/%7Eterra/cgi/lockfile.htm
では、flock以外のファイルロックにも言及があります。

Tiot [E-Mail] 1998/08/30(日) 03:29:20
またB-Cusさんの書き込みとかぶってしまいました。
>ところでどなたかNFS環境下でflockを使うとどうなるのか
>教えてください。
http://www.vsop.isas.ac.jp/ops/doc/pod/perlfaq5/How_can_I_lock_a_file_.html
http://www.kanagawa-u.ac.jp/~hibino/Lessons/UNIX/HTML-Unix4Hep-2/unix4hep2-1/node18.html
に、情報があります。
前者によれば、基本的にできるが、flockのバージョンによってはできないようです。
後者にはページの末尾にできると書いてあります(このページのスクリプトはperlでは
ないですがperlでも同じでしょう)。
NSFはあまり使ったことがないので私ではこれ以上はわかりません。

B-Cus 1998/08/30(日) 04:28:37
ありがとうございます。

むむぅ、「Some versions of flock」とはいったい…。
やっぱり実験してみるしかないようですね。

# まずはNFSのセットアップからかぁ。めんどくさいなぁ(笑)
## 誰かNFS環境がある人、やってくれません?(^^;

> 後者にはページの末尾にできると書いてあります

これはflockではなくfcntlですね。fcntlを使ってロックが
できるというのは初耳です。今度試してみよう。

って、これってperlからどうやって使うんだろう?
 flock(FILEHANDLE,FUNCTION,SCALAR)?
FUNCTIONっていったい…? SCALARはどう設定すれば…?
うーん、先は長そう。

B-Cus 1998/08/30(日) 04:32:33
>  flock(FILEHANDLE,FUNCTION,SCALAR)?

fcntl(FILEHANDLE,FUNCTION,SCALAR) でしたね。

satoshi 1998/08/30(日) 11:56:04
flockについては
http://www2d.biglobe.ne.jp/~gama/cgi/lock/lock.htm
http://eve.mogami-wire.co.jp/unix/locking.html
もご覧あれ。

がんま [E-Mail] 1998/08/30(日) 12:30:24
いろいろとありがとう瘢雹ございます!

今から頂いたサイトへ行ったりして試してみます。

satoshi 1998/08/30(日) 12:39:22
>こういう場合は、1の前にロックをかけて、3の後でロック
>解除というのがいいと思います。この場合はロックファイルを
>別に使うことになりますね。

必要ファイルが増えるのが嫌なので、僕はこうしています。

open(OLD,"data.txt");
flock(OLD,2);
@data = <OLD>;
処理
open(NEW,">data.txt");
print NEW @data;
close(NEW);
close(OLD);

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