あれ、flockの書き込みは?

[上に] [前に] [次に]
B-Cus 1998/05/15(金) 02:38:36
見付からないので、新規で書きます。


先程の書き込みでは、flockとcloseの順番については
考えていませんでした。

「Perlプログラミング」の例ではcloseしてないので
自分で考えてみました。とりあえずロックファイルを使う
場合についてですが、

#!/usr/local/bin/perl

open(LOCK,">lock");
flock(LOCK,2);

open(FILE, ">tmp");
print FILE "$$\n";
print "$$ -- ";
close(FILE);

sleep 1;

open(FILE, "tmp");
print <FILE>;
close(FILE);

flock(LOCK, 8);
close(LOCK);

というスクリプトを同時に複数実行したところ、うまく
lockできています。で、flockとcloseを逆にしても大丈夫でした。

ただ、flock、closeの順で書いた場合、lock解除の直前にファイルへの
書き込みを行って、streamがflushされないうちに(closeの前に)、
他のプロセスが同じファイルへの書き込みを終了してしまったら、
まずいようなまずくないような、、、

でもでもclose、flockの順だとそもそもlock解除する意味が
ないような、、、、

# 実際、上のスクリプトではflock(LOCK,8)をコメントアウトしても
# 動いてるんですよね。

はて? 混乱してしまった。どなたかご存じの方教えてください。

織田信長 1998/05/15(金) 13:32:15
あくまで推測なのですが、flockはいわゆる紳士協定なのでは?
・flockを使用していないプロセスからの書き込み/参照には無防備
・プログラム(プロセス)が終了すると自動的に解除される
だから、close直後でプログラムが終わるのなら、flock(8)がなくても動くのではないでしょうか?

あと、やはりcloseでファイルハンドラは無意味になるので、論理的にはどう考えてもflock→closeの順番だと思います…

kei [E-Mail] [HomePage] 1998/05/16(土) 02:10:35
あまり経験のない私がこんなこと発言するのもおこがましいんですけれど

#!/usr/local/bin/perl

open(LOCK,">lock");
flock(LOCK,2);

open(FILE, ">tmp");
print FILE "$$\n";
print "$$ -- ";
close(FILE);

sleep 1;

open(FILE, "tmp");
print <FILE>;
close(FILE);

flock(LOCK, 8);
close(LOCK);

のスクリプトでは "temp" にはロックがかかっていないですよね。
だからもしうえの "lock" というファイルを使わない場合には
"temp" に同時に書き込みすると "temp" は壊れてしまうか
すくなくとも意図した通りには作られないと思います。
おなじ "lock" を使うと最初に実行されたスクリプトが長時間
かかった場合その間ずっとwaitになるのではないでしょうか。
上記のスクリプトでは扱うファイルが1つしかないので
どのようにしても次のスクリプトは最初のスクリプトが終わるまで
待つしかないと思います。しかしロック−ロック解除までの間に
ファイルが複数あってその中のいくつかはすぐに開放したくて
出力するファイルを直接ロックしたい場合は
やはり open(f,">temp")−flock(f,2)−close(f)−flock(f,8)
でないといけないのではないでしょうか。
flock(f,8)−close(f) の順では他で書き込みがwaitになっている
場合flockとcloseのわずかの間に他から書かれてファイルが
おかしくなるのではないでしょうか。
もしかすると私ぜんぜん見当違いのことをいっているかもしれませんけれど・・・
また、すごい恥をかくかもしれませんけれどご指導していただければ
と思ってあえて投稿してみました。

B-Cus 1998/05/16(土) 03:46:30
> あまり経験のない私がこんなこと発言するのも

僕もこれまでflockを使ったことはありませんでした(笑)

> だからもしうえの "lock" というファイルを使わない場合には
> "temp" に同時に書き込みすると "temp" は壊れてしまうか
> すくなくとも意図した通りには作られないと思います。

ですね。織田信長さんの言われるとおり、flockは紳士協定です。

> しかしロック−ロック解除までの間に
> ファイルが複数あってその中のいくつかはすぐに開放したくて
> 出力するファイルを直接ロックしたい場合は
> やはり open(f,">temp")−flock(f,2)−close(f)−flock(f,8)
> でないといけないのではないでしょうか。
> flock(f,8)−close(f) の順では他で書き込みがwaitになっている
> 場合flockとcloseのわずかの間に他から書かれてファイルが
> おかしくなるのではないでしょうか。

ただ、織田信長さんの書かれている通り、closeした後の「f」には
意味があるとは思えません。

またlock解除の時点でバッファをフラッシュするような
仕様になっているなら、keiさんの心配は杞憂でしょう。
なぜなら、そうなっていた場合、lock解除した時点から
closeまでの間にtempの内容が変化することはないから
です。

ただ、lock解除の時点でフラッシュが行われるかどうか、、
には確信がないです。perlでバッファをフラッシュする
関数ってありましたっけ?

とほほ 1998/05/16(土) 11:39:05
close(F)した時点で自動的にflock(F,8)が実行されます。close(F)し
た時点ですでにFは無効なので、close(F)の後のflock(F)は無意味です。
プロセスが終了する時に、自動的にclose(F)が呼ばれます。

flock(F)が紳士協定というのはそうですね。flock()を使用していない
プロセスに対しては効力を持ちません。(これをアドバイザリロックと
か呼んでいます)

バッファフラッシュは、perl5だとautoflush()がありますが、、perl4
だと$|を用いるしかないかも。バッファフラッシュは盲点でしたね。

B-Cus 1998/05/17(日) 07:08:43
ということは、
 pen(f,">temp")−flock(f,2)−close(f)
で大丈夫ということでしょうか?

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