トップページ⇒php
981コメント337KB

【Perl】ファイルロック(排他処理)について語ろう

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0483nobodyさん03/08/31 04:22ID:???
>>482
「dbfileを使うプロセスは、かならずdbfileにアクセスする前にlockfileをロックする」
という紳士協定があればうまく行く。

dbfileにアクセスするのが>>482のスクリプトだけの場合も然り。

それでもなぜか分からないなら良く考えてみ。
0484nobodyさん03/08/31 20:24ID:???
>>482
ブロッキングを理解すると分かると思います。

flockでロックされると、LOCK_NBを指定していない限り、
排他される側はflock関数の場所で処理を止められます。
048548203/08/31 22:31ID:3rubdTEF
tieする前に必ずファイルロック処理する。
flockをLOCK_SHでした場合は%hashへの代入はしない。
上を全てのdbfileを使う処理でする。
この順番を守ればflockの段階でブロックしてtieへ進まない。
やっと、すっきりした。
>>483.484さんありがとー
0486nobodyさん03/08/31 23:56ID:???
ついでですが、ファイルを排他ロック(LOCK_EX)するときは、
書き込みできる状態でファイルをオープンしないとロックしない
OSがあるそうです。ご注意あれ。

参考:
同じ(ような)処理をするモジュール。
http://search.cpan.org/author/DHARRIS/DB_File-Lock-0.05/Lock.pm
048748203/09/01 01:40ID:???
>>486
open LOCK,'<lockfile';
ってするてことですね。気をつけます。
このモジュール結構便利ですね。
ありがとございます。
perlの面白みにはまっっていく・・土日外にでてねえ・・
0488nobodyさん03/09/01 19:13ID:???
LOCK_SHしといて、STORE〜SYNCまでの間LOCK_EXにして
SYNCがかかったらSHにもどしちゃダメ?
LOCK_EXの時間は短い方がいいとおもうんだけど
0489nobodyさん03/09/01 22:19ID:???
>>488
魅力的ですが、共有ロック(LOCK_SH)をしているところに
排他ロック(LOCK_EX)をしようとすると、
ブロックされて待たされることになります。

書き込む事がほとんどないのであれば、
検討する価値はあるかも。

ロックしたら、操作、すぐ開放が基本です。
049048803/09/02 11:52ID:???
> 魅力的ですが、共有ロック(LOCK_SH)をしているところに
> 排他ロック(LOCK_EX)をしようとすると、
> ブロックされて待たされることになります。
同じプロセスならLOCK_SHからLOCK_EXへ移行できちゃったんですが...
0491nobodyさん03/09/02 20:13ID:???
言いたかったのは、こんなイメージです。

 processA     processB
   |         |
flock(F, LOCK_SH);   |
   |         |
  処理    flock(F, LOCK_EX);
   |          :
   |          :  (ブロックされる)
   |          :
 close(F);       処理 (ここで処理開始)
   |         |
   exit;        |
            close(F);
              |
             exit;
049249003/09/04 22:14ID:???
そっか、タイミングがちょっと遅くなるだけで、結局待たされるんだ。。。
って事でhttp://www.perldoc.jp/docs/modules/DB_File-1.805/DB_File.poをみると・・・
まともにロックしたかったらBerkeleyDBを使えっと(´Д`;)

0493nobodyさん03/09/06 01:39ID:A9Khhwgn
flockでここまでスレが伸びるのか・・・。
漏れなら小規模の場合は消えるの覚悟で単純にflockだけ(面倒)。
中規模以上はDB立ててDBのLOCKで対処。

これじゃいかんのか?
0494nobodyさん03/09/06 02:09ID:???
俺もDBマンセー
0495nobodyさん03/09/06 03:10ID:???
>>493
flockで消えちゃうのは、何かお前のやり方に問題があるんだと思うぞ。
システム自体がflockの堅牢性に頼っていると言うのに。
0496nobodyさん03/09/07 02:25ID:???
flockにも限界があるので、できるなら餅は餅屋に任せるのがいいと思いますよ。
0497nobodyさん03/09/07 10:06ID:???
>>496
限界って?
Windowsやover networkでうまく働かない以外に何か問題あったっけ?

だいたいflock使えねーとか言ってるヤツのコードみると書き方間違ってる
だけだったりするんだよな。

ごちゃごちゃ言う前にモジュール使えってのはまぁ同意だけど。
0498nobodyさん03/09/07 14:44ID:AN0xO5Ef
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

ありますよ。ご自分でお調べください。
0499nobodyさん03/09/07 15:01ID:???
>>498
あとは昔のOSでバッファをフラッシュしないくらいしか思いつかないなあ。

UN*X系のOSで別に正しく使えばファイルが消えちゃうとかはないでしょ?
0500nobodyさん03/09/07 15:03ID:???
UNIX系でflockに対応してないものもある、見たいなのを読んだ事があるけど本当ですかね?
0501nobodyさん03/09/07 15:04ID:???
>>499
>>496=498は適当に言ってるだけですよ。
0502nobodyさん03/09/07 15:14ID:???
そんな感じだな
050349603/09/07 19:04ID:???
>>497
flockでデータベースを丸ごとロックするより、
他の方法を使ったほうが限界性能が上がると言いたかったのですが…。

別の話として。
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?
ActivePerlの場合、WIN32APIのLockFileEXが使えれば、Windowsでも使えます。
そして、それはうまく働きます。

私はflock(2)の信頼性を否定しません。
とはいえ、perlのflockについてはperldocに例外事項が書かれています。
(498さんの言いたかったのはこれかな)

perlのflock関数 = flock(2)であるとは限りません。

参考:
perldoc -f flcok
perlソース pp_sync.c
ActivePerlソース win32.c
0504nobodyさん03/09/07 22:04ID:???
>>503
おいおい、何はぐらかしてんだ?
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
他の方法とは?
0505nobodyさん03/09/07 22:26ID:K46D6zau
flockからunlockまでの途中で強引に処理を止めて、同じcgiを複数
起動させればflockの信頼性が判るよ。いくつかはロックかからずに
スルーされるからさ。

後はロックの残骸による次プロセス(同一ロック)の停止かな。
遠回りしないと解決出来ないのは面倒。

漏れが間違っているかもしれんが、同時に数千〜数万単位でロックを
必要とする環境に置いて上記の理由からflockは使いたくないです。
よってほとんどDBのロックに任せっきり。DBだと単純なa=a+1の場合だと
DB自体が保証してるんでロック不必要だし。

間違っていたら本当にスマソ。業務でロックを故意に壊しにいった結果
こうなったので。
0506nobodyさん03/09/07 22:35ID:???
>>505
ソースとdfの結果みせてみな。

そういうケースの殆どはファイルシステムがNFSだった、って
オチな訳だが。

もし本当にflock(2)に信頼性がないなら、sendmailがmailboxファイルを消しまくる
現象が世界中で起きてるはずだが。

> 後はロックの残骸による次プロセス(同一ロック)の停止かな。

・・・は?

> 間違っていたら本当にスマソ。

多分間違ってると思う。
0507nobodyさん03/09/07 23:19ID:???
>>505
>いくつかはロックかからずにスルーされるからさ。
どうやって判断してんだ。テストコードがバグってんだろ。よくあることだ。

>ロックの残骸
って何?

>flockは使いたくないです。
>よってほとんどDBのロックに任せっきり
・・・
0508nobodyさん03/09/07 23:54ID:???
最近は、凧や独楽を買ったものの、子供がうまく使いこなせずに「不良品じゃないのか!」と
店に怒鳴り込む馬鹿親がいると聞きますが・・・。

この業界にも、道具を使いこなす努力をせずに、自分の無能を全部道具のせいにする
DQNが増えてきたってことですかね。
0509nobodyさん03/09/08 10:14ID:???
>508
ハゲドウ

しかし、不良だらけの道具を平気で売ってる大企業とかも在るのが実情ではある。
M$とか。
051049603/09/08 13:21ID:???
>おいおい、何はぐらかしてんだ?
>>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

perldoc -f flockから引用
>Calls flock(2), or an emulation of it, on FILEHANDLE. Returns
>true for success, false on failure. Produces a fatal error if
>used on a machine that doesn't implement flock(2), fcntl(2)
>locking, or lockf(3).

>On systems that support a real flock(), locks are inherited
>across fork() calls, whereas those that must resort to the more
>capricious fcntl() function lose the locks, making it harder to
>write servers.

というように、いい加減なfnctl(2)によりエミュレーションされた場合は
サーバーの書き込みが激しい場合ロックが失われると書いてあります。

>>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
>他の方法とは?

データベース側に専用のロック機構があれば、そちらにお任せしますが?
全部flockしますか?
0511nobodyさん03/09/08 23:47ID:???
>>510=>>496
こいつ何言ってんだ?勝手にデータベース使うな。
0512nobodyさん03/09/09 02:09ID:???
>>510
んじゃ、perlにflock(2)の呼び出しが実装されてれば問題がないということでよろしい
でしょうか?

俺は思わず「fcntlがダメダメ -> POSIX準拠と呼べない -> UNIX系とも呼べない」
と思ってしまったが。
051349603/09/09 20:09ID:???
>>512
flock(2)が機能して、正しく使えていれば問題ないかと。
私の知る限りでは、fcntl(2)でも十分信頼性はあると思いますけどね。
0514nobodyさん03/09/12 14:11ID:e1VX9Ox6
flock(2)とPerlのflockを混同するから話がややこしくなるんだよな。

flock(2)はover networkじゃなく、正しく使えば基本的に堅牢。
Perlのflockはコンパイルされた環境依存、ってとこか。
fcntlでもちゃんとPOSIXに準拠してれば問題ないはず。

その腐ったfcntlを実装してるOSが何なのか知りたい。
Larryの事だから、誰も使わないようなかなりマイナーな物を
想定しているような気がするが。

しかしfcntlは堅牢でないからDBを使う、といってる人がいたが、
じゃぁそのDBはどうやってファイルをロックしてるんだろう?
0515nobodyさん03/09/12 19:43ID:???
システムのロック以上の能力を持つロックは不可能です。

と言い切ってみるテスト…。
0516nobodyさん03/09/13 00:45ID:???
fcntl がクソな実装を具体的に挙げられない限り、flock 否定派の香具師は議論にならん。
0517nobodyさん03/09/13 23:39ID:???
>>516
UNIX系ならまず大丈夫、ということで良いだろ。
fcntl失敗する時点でUNIX失格だからな。
0518nobodyさん03/09/14 21:13ID:???
>>514
PostgreSQLだったらセマフォ。

>>517
http://qmail.jp/mta/spool.htmlでも触れられているが、
NFSでlockdが腐る現象がまれに発生する事を実際に経験している。
(俺は信者じゃない)
051951803/09/14 21:24ID:???
> PostgreSQLだったらセマフォ。
これ、やっぱ嘘かも。
しかし、排他制御のプリミティブはfcntlやflockだけではない。
0520nobodyさん03/09/15 06:39ID:???
突然だけどflockってなんて読んでる?
0521nobodyさん03/09/15 06:42ID:???
えふろっく
0522nobodyさん03/09/15 07:54ID:???
ファイナルロック>510
0523nobodyさん03/09/15 10:38ID:???
限界でもファイルロックだろうね。
0524nobodyさん03/09/15 17:19ID:???
search.cpan.orgで、flockとかfile lockをキーで引いてみると
結構でてくるのですが、どれかお勧めはありますか?
それとも毎回自分で処理を書いたほうがいいのでしょうか?
0525nobodyさん03/09/15 18:11ID:???
このスレでそんな質問しても無駄。
「flock は腐ってる。 DB 使え」という答えしか返ってこない。
0526nobodyさん03/09/15 23:20ID:???
>>524
それぞれ用途が違うから、必要に応じて使えばいい。
0527nobodyさん03/09/15 23:44ID:???
>>525
そんなこと書いてるのは約一名だろ。

>>524
perl -MConfig -e 'print $Config{d_flock}."\n"'

これ実行して「define」と出ればflock(2)が実装されてるからまず大丈夫。
ネットワーク越しでなければラクダ本に書いてあるflockのサンプルで充分。
0528nobodyさん03/09/16 00:04ID:???
ラクダ本の見て必要無いのにseek(FH, 0, 2)とかやってる奴
何人か見た事あるので充分なのかどうかは微妙とか言ってみるテスツ。
0529nobodyさん03/09/16 01:04ID:???
最近はseek(FH, 0, 2)いらんよね
0530nobodyさん03/09/16 02:04ID:???
>>528
別にseekやってもオーバーヘッド以外の害はないんだし、害がある場合もレアケースながら
存在するので、的確かどうかはともかく、少なくとも「充分」ではあるのでは?
0531nobodyさん03/09/27 12:58ID:???
こんなロック処理はどうだ?

mkdirで新規ディレクトリを作ったうえで、ロック成立条件を満たした場合にロック完了とする。
ディレクトリ名にタイムアウト時刻と共有/排他ロックの種別を埋め込む。

共有ロック時はディレクトリ作成後に、親ディレクトリのファイルリストを取得して、
自分の作ったディレクトリよりも前に排他ロックディレクトリが作成されていなければ、ロック完了。
排他ロック時も同様に、自分の作ったディレクトリよりも前にディレクトリが作成されていなければ、ロック完了。
もちろん、ファイルリスト取得時にタイムアウト時刻を過ぎたディレクトリは消去する。

環境依存せずに、read-write lock patternをperlで実装するとこうなるね。
0532nobodyさん03/09/29 13:16ID:???
環境依存せずに。。。という話なんだけど、
flockサポートしてない環境ってそんなに一杯あるんですか?
windows 9xでサーバ立てる香具師はほっといたとして、、、
nkfのlock機構って精度低いんですか?
0533nobodyさん03/09/30 04:58ID:???
>>532
nkf の lock 機構ってのは聞いたことないんだが、

・・・っていうか、一体いつまでおんなじような議論を堂々巡りで続ける気なんですか?!?!
0534nobodyさん03/09/30 05:00ID:???
あ、ところで、 >>531 の方法は、
なかなか良さげっていうか、問題無さそうな気がするんですがどうなんでしょうね?
053553203/09/30 11:52ID:???
nfsの間違えでした(スマソ
0536nobodyさん03/09/30 12:29ID:???
>>534
ほぼ同じ仕様のコードが既に公開されてて、有難く使わせて頂いてます。
053753103/09/30 17:11ID:???
>>536
どこで公開されてたか教えれ!
0538nobodyさん03/10/02 03:29ID:???
>>536
もしかして、ここかしら?
ttp://www.mindcompass.sfcgi.com/200303.html
053953103/10/02 09:02ID:???
>>538
やっぱうちのサイトですか(w

で、今改良版を作ってるのですが、タイムアウト時刻をディレクトリ名にすると、同時にタイムアウト時刻が
違うロックを作ると誤動作するな。

だから、現在時刻をディレクトリ名にして、ディレクトリの作成時刻をタイムアウト時刻に変更すると言う
アクロバティックな操作が必要かもね。

改良版出来上がったら公開しますか?(y/n)

0540nobodyさん03/10/02 16:33ID:???
>>539

自作CGIを評価するスレ
http://pc2.2ch.net/test/read.cgi/php/1049514428/470

何これ。恥ずかしがりやさんなのかな。
0541nobodyさん03/10/02 22:14ID:???
>>540
さんくす。こんなスレがあるとは知りませんですた。
さっそくそっちのほうにageてみました。
0542nobodyさん03/10/03 18:38ID:???
>>541
いやいや何か勘違いしてない?
ファイルロックの話なんだからこのスレでいいだろう。

俺の言いたかったのは>>539の最後に(y/n)があって、
何故かhttp://pc2.2ch.net/test/read.cgi/php/1049514428/470 で
yと答えてたので報告したまでです。
0543nobodyさん03/10/03 18:51ID:???
>>531
これって安全そうでよさげな気はするんだけど、
ちょっと思ったんだけど、ものすごくアクセス多い場合に、
ディレクトリ作成〜ファイルリスト検査のタイムラグのせいで、
いつまでたってもだれもロックを取得できない、ってな状況になりそうな気がする。
054453103/10/05 10:57ID:???
新バージョンageてみました。
今度の奴は、ロックする側のプロセスがタイムアウト時間を個別に設定できます。

http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/lounge/index.html

>>543
確かにファイルリスト検査に時間がかかるが、ならばどうしろと?
0545nobodyさん03/10/06 12:54ID:???
>>544
いや、どうすればいいか私にも思い付きません。すいません。
単にデメリットを挙げてみただけで、
だからといってその方法が使えねーとかいう気も毛頭ありません。
054653103/10/06 22:56ID:???
>>544>>545
さらに一念発起してrename方式に変更してロック処理にかかる負荷を低減してみました。

rename方式でテストしたらロックがぶっ壊れるなー、とか思ってたら
ロック検証用のルーチンの書き方に問題があった罠。
同じファイルを読み込みと書き込みで2回オープンして、しかもバッファ処理をカットしてなかったので、
スクリプト上では書き込んだつもりでもファイルシステム上では「まだ」書き込まれてない場合があることに
ようやく気がついた。

教訓。
ロック処理が正しくても、ファイル入出力の部分の書き方によっては思わぬファイル破損がありうる。
054753103/10/07 18:17ID:???
>>546
やっぱりread-write lockってむづかしいでつね。
rename方式だと、共有ロックをかけているプロセス数が分からないといつロック解除していいかわからない。
ロックプロセス数を安全に記録するために、内部で排他ロックをかけなければいけない罠w
これでどのくらいロック処理で負荷がかかるか、だな。
0548nobodyさん03/10/29 05:07ID:???
複数ファイルにまとめてロックを掛けるにはどうすれば良いのですか?

例えば掲示板で最初のページだけ静的なファイルにしたいという場合、
ログとその最初のページの両方を同時にロックしないといけないので。

FLOCKのディレクトリ版とかあれば便利なのですが…。
0549nobodyさん03/10/29 06:01ID:???
>>548
ロック開始と解除の間で必要なファイルを扱えばいいだけ

ロックの仕組みを根本的に理解していないんじゃないか?
もうちょっと勉強せい
0550nobodyさん03/10/29 08:13ID:???
【Perl】ファイルロック(排泄処理)について語ろう
http://pc2.2ch.net/test/read.cgi/php/1024795138/
0551nobodyさん03/11/03 16:44ID:???
>548
ttp://www98.sakura.ne.jp/~jun/perl/flock.html#02
0552nobodyさん03/11/05 02:38ID:???
>551
flockってロックしたファイルが閉じるまでに開いた他のファイルまで
全部ロックしちゃうの?
0553nobodyさん03/11/05 04:25ID:???
>>552
お前、リンク先のサイトの内容ちゃんと読んだか?
0554nobodyさん03/11/05 11:35ID:???
>>551
リンク先面白かった。初心者にもわかりやすい情報をWebで公開してくれる人って、尊敬。
0555nobodyさん03/11/05 14:16ID:???
>>553
読んだけど。
かいつまんで書くと

lockfileを開く
lockfileをロック
count.txtを開く
上書き
count.txtを閉じる
addr.txtを開く
追記
addr.txtを閉じる
lockfileをアンロック

だよね。
count.txtとaddr.txtには直接ロックかけてなくて
lockfileをロックすることによりこの二つのファイルもロックされてるらしいから
>551みたいに言った。
0556nobodyさん03/11/05 14:16ID:???
552だ。
0557nobodyさん03/11/05 14:28ID:???
ああ何となく解ってきた。
よく考えたらlockfileがロックされてるときはそこから先に進まないから大丈夫なのか。
0558nobodyさん03/11/08 02:04ID:???
ロック用ファイル作らなくても
どっちかのファイルにロックかけて最後まで開いてるままで十分だけどな。
0559nobodyさん03/11/08 13:26ID:???
>>558
あんた無茶苦茶言いますなぁ・・・
0560nobodyさん03/11/08 13:37ID:???
無茶苦茶???いったい何が???
0561nobodyさん03/11/08 15:28ID:???
>>559
count.txtにロックかけてそのままabbr.txtの処理終わるまで開いときゃ良いじゃん。
0562nobodyさん03/11/08 17:35ID:???
addrだった。
0563nobodyさん03/11/09 03:10ID:???
>>561
レアケースだろうけど
似たような事して壊れたことあるよ
無茶苦茶って事では無いだろうが、
そのやり方だと同時オープンで
2人アクセスしてきたのに1しかカウントアップしないって
ケースがタイミング良ければ発生する程度かな
0564nobodyさん03/11/09 10:32ID:???
>>561
どうやってロックするんですか?
0565nobodyさん03/11/09 14:47ID:???
>>563
なんでそうなる?単にヘボ実装だっただけじゃないの?
0566nobodyさん03/11/09 15:19ID:???
>>563
なるわけないだろうが
0567nobodyさん03/11/09 18:12ID:???
>563
単に読み込みをブロックしてなかっただけってオチなんじゃ。
それか二つのファイルでファイルハンドルを同じにしちゃったとか…。

>564
open(COUNT, "+<$cfile");
flock(COUNT, 2);
(中略)
open(ADDR, ">>$afile");
(中略)
close(ADDR);
couse(COUNT);
0568nobodyさん03/11/09 18:18ID:???
ちょっと複雑なシステムで
複数のスクリプトが複数の同じファイルを読み書きする場合は
ロック用ファイルを一つ用意する方が管理が楽なのは当たり前。

でもカウンターのようにファイルが単一のスクリプトからしか読み書きされない場合は
どちらか先に読む方のファイルをロックしておけば十分。
0569nobodyさん03/11/09 18:46ID:???
>>565
>>566
無能か?(w
ググルとたくさんでてくるぞ、そのケース
0570nobodyさん03/11/09 18:58ID:???
わけわかんね。
サーバがflockをきちんと使えないシステムを採用してたとかじゃないの?
0571nobodyさん03/11/09 19:03ID:???
>>569
きっと君と同じぐらい無能なやつなんだろうね
ここでそんなこと言ってるのも君ぐらいだし
0572nobodyさん03/11/09 19:42ID:BVCYv2fe
>>570,571
馴れ合いはよそでやれよ・・・
ま、>>555は書いてるとうりにすれば問題無し
わざわざ混乱させんでもよかろうに
057357203/11/09 19:48ID:???
ageちまっていいスレだよな・・・

それか、
>>567-571はジエン厨じゃあなかろうなぁ?
0574nobodyさん03/11/09 19:55ID:4SnYD/Cs
 | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
 |.本日選挙は20時迄!|
 |__________|
   ∧∧ ||
   ( ゚д゚)|| <残り10分切ったど!
   / づ     投票してない香具師は自衛隊の代わりにイラク逝けよ。

※総務省によると、総選挙の中間投票状況は
9日午後4時現在、全国平均で40.04%。前回を1.40ポイント下回っている。
0575nobodyさん03/11/09 19:59ID:???
>>573
あれが自演ならお前さんも>>569か?って事になるじゃん…。
本当だったら煽った挙句自演呼ばわりですかって感じで笑えるけど。
0576nobodyさん03/11/09 20:28ID:???
>>569
ハァ?
じゃあ「そのケース」とやらをここに貼れよ。
そのヘボ実装を検証してみようや。
0577nobodyさん03/11/09 20:54ID:???
>>572
馴れ合い?
0578nobodyさん03/11/09 21:14ID:???
>>577
「馴れ合い」の意味を知らないだけだろ。無知は構うな。ほっとけ。
057956403/11/10 14:47ID:???
あれ?flockが使える環境の人もこのスレの需要あったの?
まぁどっちでもこの場合変わらないけど。
0580nobodyさん03/11/10 14:53ID:???
>>561が勝手にflockと勘違いして
勝手に自分のやり方を押しつけたって事かぁ(・∀・)
0581nobodyさん03/11/10 16:11ID:???
>>580
ということにしたいのですね? :-)
0582nobodyさん03/11/10 16:19ID:???
もうほっとけほっとけ
0583nobodyさん03/11/10 16:43ID:???
♪か〜な〜しみ〜に〜であうた〜び〜
■ このスレッドは過去ログ倉庫に格納されています