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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0682nobodyさん04/04/30 17:27ID:???
という事で、bindでロックをかけようとしたが、Windows(Me)上ではいくらでもbind出来てしまうので意味無し。
そんな物を使うぐらいならソケットでプロセス間通信をしてしまう方が楽であると思うが、
Perlなんかでそんな事したらパフォーマンスが(以下略
0683nobodyさん04/05/19 04:13ID:???
すいません。PERLのCGIでtxtファイルを読みこむんですが、読みこみだけの場合でも排他制御は必要でしょうか?

誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。
それが嫌な場合は

open(DATA,"< test.txt");
flock(DATA,1);
なんたらかんたら
close(DATA);

みたいにして一人がオープンしている間は別プロセスには待たせればよろしいんでしょうか?
flockの説明を見てみると読みこみだけの時用の番号がなかったので、不安です。自分のPCはwin98なのでflockは使えませんし、
鯖にぶつけ本番はいやだなと思って聞きにきました。
0684nobodyさん04/05/19 04:50ID:???
>>683
みんな読むだけだったら別に排他制御は全然要らんよ。
0685nobodyさん04/05/19 07:03ID:???
683氏に似た質問です。

書き込みの処理が2つ以上同時に行われないと分かっている場合
かつ、一過性の読み込み失敗を許容する場合
書き込みにロックは不要ですか?
0686nobodyさん04/05/19 09:38ID:4B5lUTgr
Dirty readを許すのか、許さないのか?
話はそれからだ
0687nobodyさん04/05/19 11:10ID:???
>>685
「ロックとは何のために必要なのかを教えてくれ」という質問と等価と考えてよいのかな
068868304/05/19 17:00ID:???
>>684
いらないんですか。ということはアクセス集中によるオープンエラーは読みこみだけならば
起こらないということですか?

本当は自分でその状況を作り出してテストしてみたいんですけど、動作テストはwin98に入れたhttpdなので
同時アクセスが試せないんですよね。

ファイルオープンするCGIがユーザに色んな項目を記入してもらった次のページなのでエラーが
でちゃうとまた、入力してもらう事になってしまうのでそれはまずいなと思いまして;
0689nobodyさん04/05/19 18:15ID:???
>誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。

これがそもそも勘違いだしな。
0690nobodyさん04/05/19 19:43ID:???
>>688
Windows はどうだか知らんけど、
UNIX なら読み出すだけならアクセス集中でオープンエラーなんてないだろ。

つーか、そこまで信頼性高いシステムが必要なら、2ちゃんなんかで質問するより、
もっとちゃんと調べて勉強するか、外注に出した方が良いんじゃないか?
069168304/05/19 23:00ID:???
>>689
ありがとうございます。
吐いた制御ってオープンエラーを防ぐんじゃなくて、書きこみが同時に行われてファイルが壊れるのを
防ぐためにあるってことですね。

>>690
ありがとうございました。
069268504/05/20 15:35ID:???
>685です。レスが遅れてすみません。
返答ありがとうございます。

>>686
Dirty readとは書き込み中に読み込めるということで、最新でないものを読み込めてしまうということでしょうか。
それは構いませんし、リロードで直る一時的なものであれば読み取りが0バイトでも構いません。

>>687
そういう事になるかも知れません。
言い換えると
書き込み処理が重複しない時、理論的にファイルが壊れるか否かが知りたいのです。
0693nobodyさん04/05/20 20:28ID:???
ファイルを壊す原因は山ほどあるが、
その中でも「書き込み処理が重複する」という原因はよく起こる。
この重複を避けるための道具が、ファイルロック。

ロックは、これさえかければファイルが壊れなくなるという魔法の杖ではない。
ロックは単なるプログラミングの道具に過ぎず、
それも、ファイルを壊さなくするための道具ではなく、
書き込みが重複しているかどうかを識別するだけの道具。
識別した上で書き込みが重複しないようにプログラムを書くのは、プログラマの責任。

逆に、書き込みが重複しないということが100%保証されているなら、
ロックをかけてもかけなくても変わらない。
もちろんその場合でも、書き込み処理重複以外の原因でファイルが壊れることは、いくらでも考えられる。
0694nobodyさん04/05/20 20:38ID:???
書き込みが重複しないということをロック以外の方法で100%に近い精度で
保証する方法なんてあるのか?
0695nobodyさん04/05/20 21:07ID:???
>〜するだけの道具。
まではいい事言ってると思うんだが最後の方になって壊れてるな。
0696nobodyさん04/05/20 22:40ID:???
>>694
単に、書き込みが100%重複しない論理空間を仮定すれば、というだけの話でしょ。
もちろん現実にそんなことはありえないと暗示しているわけで。
069768504/05/21 01:02ID:???
皆様回答ありがとうございます。

>>693
という事は書き込みが重複しないなら、
ファイルロックで防げる程度のトラブルは防げるという事ですね。

>>694
書き込み処理を行えるのがパスワードを知っている1人なのです。
パスワードが他人に漏れず、その1人が同時に操作せず、
openしたまま処理が中断することもない・・・
という仮定はありますが。

ファルイロックの基本的な知識さえない私に丁寧な回答ありがとうございました。
0698nobodyさん04/05/27 13:48ID:???
やっと最近になってきっちりしたファイルロックのコード書けるようになった。

けっこうウソ書いてあるサイトが多いのに驚いた。
0699nobodyさん04/05/27 17:15ID:???
>>698
そういうサイトもきっちり書けていると思ってんだろ。
お前と同じように。
0700nobodyさん04/05/27 20:14ID:???
きっちり書けるようになったと自分で思い込むのは勝手だが、他人には言うな。
0701nobodyさん04/05/27 21:10ID:???
どうキッチリ書いたか教えて欲しい
0702nobodyさん04/05/27 21:08ID:???
どう書いたか教えて欲しい
0703nobodyさん04/05/28 01:38ID:???
うん
見せてよ
070469804/05/28 11:16ID:???
わたしは秘密主義なんで弟子にも教えることはない。

自分で掴み取れ!  これに尽きるな
0705nobodyさん04/05/28 15:29ID:???
ふっ。これで糞コード蔓延の芽がまた一つ摘み取られた。良かった良かった。
0706nobodyさん04/05/30 14:43ID:???
ファイルロックなんかしなくったって、めっちゃ速く処理してしまえばええやん
0707nobodyさん04/05/30 14:44ID:???
>>706

すげー!! それだっ!
0708nobodyさん04/05/30 18:12ID:???
ファイルロックなんかしなくったって、誰もアクセスしなければええやん
0709nobodyさん04/05/30 22:14ID:???
windowsならmutexを使う手があるよん。名前にファイルパス(\は/に置き換えたやつ)
を使う。速いしいいぞ。
071070904/05/30 22:16ID:???
はっ、ここはPerlの板だった。
xs使って作るしか、、、。
0711nobodyさん04/05/30 22:23ID:???
>>709 Win32::Mutex
http://search.cpan.org/~gsar/libwin32-0.191/
0712nobodyさん04/05/31 00:08ID:???
おお、あるんだ。
他のOSとかもないのかな。
lock::mutexとかいう一本にまとめて使えるようなライブラリがいいなぁ。
mutexもセマフォも使えないけどflockは使えるOSだったら、
内部実装はflockでやるとか。
071335704/05/31 20:57ID:???
flock使えない機種でmutexを使ってflock模擬したほうがいいか。
071471304/05/31 22:53ID:???
うわ、名前間違えた。
0715nobodyさん04/10/09 22:28:45ID:???
ダレモイナィ
タアソウスルナラ イマノウチ
0716nobodyさん04/10/09 23:12:22ID:???
open(LOCK, ">lock.tmp");
flock(LOCK,2);
open (IN, "count.dat");
$count=<IN>;
close(IN);
$count=$count++;
open (OUT, ">count.tmp");
print OUT $count;
close(OUT);
rename("count.tmp","count.dat");
unlink("lock.tmp");
flock(LOCK,8);
close(LOCK);

これでOK?
0717nobodyさん04/10/10 04:46:13ID:???
萌えは初心者だから良くわからないけど、
$count=$count++;
は
$count++;
でいいと思うけど。
0718nobodyさん04/10/10 16:53:04ID:???
>>716
いいえNG
071971604/10/10 16:59:43ID:???
>>718
どこら辺がNG?
0720nobodyさん04/10/10 17:10:11ID:???
無駄なことをやってるだけだろ

open (IN, "count.dat");
flock(IN,2);
$count=<IN>;
$count++;
print IN $count;
close(IN);

これでいいじゃん
072171604/10/10 17:16:22ID:???
えっ?それじゃ書き込めないのでは?
0722nobodyさん04/10/10 17:19:40ID:???
すまん

open (IN, "+>count.dat");
072371604/10/10 17:36:23ID:???
カウンタだとそれでいいけど、掲示板など複数のファイルを弄る場合にはロック用のファイルが必要になるよね?
0724nobodyさん04/10/10 17:43:35ID:???
>>723
そんなのは一概には言えない。
各ファイルは読み込み・書き込み・両方のいずれなのか、
一度に連続して読み書きするのかなど。
0725nobodyさん04/10/20 14:16:48ID:ejI/DpjA
aaa
0726nobodyさん04/10/21 19:09:46ID:wxBAgdgR
perl,phpの両スクリプトから書き込みがあるファイルがあるんだが、
mkdirとかにしといた方が無難かね?
それぞれでflock()したって排他かからない?
0727nobodyさん04/10/21 19:24:18ID:???
実装言語がどれでも中では flock(2) を呼ぶわけだし flock() で問題ないんじゃない?
0728nobodyさん04/10/21 23:27:35ID:???
>>727
デマ飛ばすな。ボケッ

man perlfunc
flock FILEHANDLE,OPERATION
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). flock is Perl's portable file locking interface,
although it locks only entire files, not records.
0729nobodyさん04/10/22 01:27:00ID:W+TTmfbF
>>727
なるほど、結局perl,phpのflock()が同じシステムコールを使うかどうかって所ですかね?
linux(redhat)なんですが、普通にflock(2)使ってると思って良いのかなぁ。
0730nobodyさん04/10/22 17:20:32ID:???
通常、perlのflock()もphpのflock()も、下位レベルで使ってるシステムコールはflock(2)なわけだが。
0731nobodyさん04/10/23 01:59:39ID:???
言語, OS, ファイルシステム等の実装に依存
php4.3.9/linux はソース確認したところ flock(2) 使ってないよ。fcntl(2)。
0732nobodyさん04/10/23 02:53:34ID:???
perl5.8/linuxはflock(2)だっけ?fcntl(2)だったっけ?
0733nobodyさん04/10/23 04:34:45ID:???
ごめん、phpでもflock(2)使ってた. -->731は間違い
双方とも flock(2) が使える環境では flock が使われる.

また間違ってるかも知れないので、調べたソースを書いておく。
php-4.3.9 ./ext/standard/flock_compat.c
perl-5.8.5 ./pp_sys.c
0734nobodyさん04/10/23 13:22:56ID:???
おお、すばらしい。
flock(2)使える環境って前提になるが(BSD,SystemV,Linux?)、PerlでもPHPでもflock()でいけるのか。
NFS上のディスクは別として。
0735nobodyさん04/10/25 18:24:04ID:???
なるほどねぇ
0736nobodyさん04/10/25 19:07:12ID:???
lockアゲ
0737nobodyさん04/11/06 19:49:00ID:em3fuQlS
 
0738nobodyさん04/11/06 19:58:00ID:???
flock最強神話
0739nobodyさん04/11/07 05:49:26ID:???
RDBMSで行ロック最強
0740nobodyさん04/11/07 23:08:21ID:???
結局、KENTのmkdirやsymlink、初心者のよく使うflock、どこかでみたrename、格付けするとどうなの?
0741nobodyさん04/11/08 00:05:16ID:???
>>740
格付けなんて意味ないのでは?適材適所でしょ。
0742nobodyさん 04/11/08 00:10:15ID:???
>>740
flockを使う奴は素人だといいたいのか〜(w
0743nobodyさん04/11/08 00:30:26ID:???
>>740
KENTは素人じゃないといいたいのか〜(w
0744nobodyさん04/11/08 13:12:26ID:BIj8xOyZ
最終兵器ロックオン・レーザー搭載!

「一度捕まえたら、離さない・・・・・」

TAITOの名作シューティングRAY・FORCEができるのは
セガサターンだけ!
074574004/11/08 21:24:24ID:???
いや…そういう訳じゃ…
0746nobodyさん04/11/08 23:46:08ID:???
cmpxchg最強
0747nobodyさん04/11/09 03:55:57ID:???
>>744
レイヤーセクションじゃなかったっけ?
0748nobodyさん04/11/09 07:25:54ID:???
>>740
flock>>>>>越えられない壁>>>>>rename=symlink>>mkdir
0749nobodyさん04/11/09 08:59:34ID:???
flockはNFS介して使うと壊れるから糞
0750nobodyさん04/11/09 13:16:33ID:???
激しくループしてるな。
0751nobodyさん 04/11/09 13:43:34ID:???
ネタがファイルロックだけだから進展しようが無い
0752nobodyさん04/11/09 20:07:15ID:???
>>749
NFSを使った事無いので、良く分からないので教えてください。

NFSを利用する時はflock関数にflock(2)ではなくfcntl(2)を利用するように
perlをビルドすると思いますが、それでもロックは壊れるのでしょうか。
fcntl(2)で壊れる場合、実際の解決手段として、どのようなものがあるのでしょうか。
0753nobodyさん04/11/10 00:42:16ID:???
>>752
Maildir
0754nobodyさん04/11/10 01:28:10ID:???
>>753
djb 厨ってホントにいつも頭使わずに発言するなあ。
0755nobodyさん04/11/10 21:25:46ID:???
>>753
それは、ロック機構が無くても信頼できるメールボックスの話だと思うのですが、
一般的なファイルアクセスにも使えるのでしょうか。
0756nobodyさん04/11/12 07:07:11ID:djvAfFkI
>>747
レイフォース >>>> 越えられない壁 >>>> レイヤーセクション
075775204/11/13 13:06:05ID:???
調べてみたところ、
・NFS Version4なら、ロック機構が組み込まれているので問題が無い(flock(2)でok?)
・NLM(Network Lock Manager)プロトコルに対応したサーバとクライアントならば、
fcntl(2)で対応可能。(ただし、一部のシステムで信頼が無いかも)
・それ以外はロックファイルを作るのが一般的
という感じらしいことが分かりました。
ありがとうございました。
0758nobodyさん04/11/13 15:51:42ID:6imth/Ie
>756

レイストーム >>> レイフォース >>> レイクライシス
0759nobodyさん04/11/14 12:08:06ID:???
レイフォース=ガンロック >> php >> perl >> レイヤーセクション >> レイストーム / レイクライシス
0760nobodyさん04/11/15 01:32:31ID:???
なんか、SIMPLE1500のTHEダブルシューティングが欲しくなってきたw
0761nobodyさん04/11/18 09:27:07ID:upfr9/ei
>>760
それなに?
0762nobodyさん04/11/18 10:10:24ID:3NzX+MnA
俺もレイ・フォースは好きだったな
懐かしい
0763nobodyさん04/11/18 19:52:46ID:GLzLqJbZ
>>762 同意。
0764nobodyさん04/11/18 20:49:35ID:???
おめーらロックすんぞ
0765nobodyさん04/11/27 15:36:14ID:o5xdYnQz
ファイルロックって読み込むときは必要無いの?
0766nobodyさん04/11/27 15:54:59ID:???
ロックするべ?
0767nobodyさん04/11/27 17:40:53ID:???
>>765
書き込みが行われず中身が固定のファイルなら不要
0768nobodyさん04/12/04 12:35:02ID:???
質問しに来たらすでに同じ質問してる人がいた。

>>765-767
サンクス

過去ログは見るもんだ。
0769nobodyさん04/12/04 19:37:01ID:???
それは過去ログって言わないけどな
0770nobodyさん04/12/20 07:41:20ID:???
追記モードのやつを読むときはいらないんじゃないの?
壊れてる可能性のあるところってバッティングしているときのだけでしょ?
0771nobodyさん04/12/20 14:13:21ID:sskqg6P0
phpとperlでflock関数でファイルロックをしてますが
現在1つのスクリプト中に複数の箇所でファイルロックを使ってます。
これらのファイルロックを全てやめて代わりに、
スクリプトの一番最初でダミーのファイルにロックをかけて
スクリプトの一番最後でロックを解除するようにして他のプロセスが
スクリプトを実行しているときはスクリプトの実行自体を順番待ちさせて
同時に複数のプロセスがファイルへの書き込みをできないように
変えようと思いますが、何か問題あるでしょうか?
1つ気になるのは、もしスクリプトの途中でexit関数等でスクリプトの実行が終了した場合は
自動的にダミーファイルのロックが解除されファイルも自動的にcloseされますか?
0772nobodyさん04/12/20 15:14:56ID:???
>>770
追記であろうがなかろうが書き込みはロックした上で行われるのなら
読み込みだけのときはロック不要。
0773nobodyさん04/12/20 15:30:20ID:???
>>771
プロセスが死ねばロックは解除される。
先頭と末尾でロックと解除をするようにするのはいいが、
パフォーマンス低下は明らか。
0774nobodyさん04/12/20 16:09:04ID:???
mod_perl や mod_php のときって
スクリプトの実行が終了してもプロセスは死なないと思うけど
mod_* がスクリプト中の flock の後始末を面倒見てくれるんですよね?
0775nobodyさん04/12/20 20:09:18ID:???
>>770
二つ以上のプロセスが同時に追記したら、データが混じる可能性があるし。

>>772
勧告ロックはそうはいかない。

>>774
PHPは面倒みてくれるけど、mod_perlのファイルハンドルは無理。
だから、IO::File,FileHandleモジュールなどを使う。
http://perl.apache.org/docs/1.0/guide/porting.html#Filehandlers_and_locks_leakages
077677004/12/20 21:19:18ID:???
>>772
ロックしなくて読んでいいのは、追記モードのときだけではないの?
上書きモードだと一旦中身が空になるわけで、そのときロックしないで
読んでしまったらだめだよね?

読み込んで、それをそのまま出力しておしまいな 2ch の read.cgi
みたいなやつならそういうアプローチもいいだろうけど、読んだデータ
を処理に利用する場合はだめと思う。

>>775
>>770 のやつ 「書込時にちゃんとロックする前提で」っていうのが抜けてた。スマソ
077777104/12/20 21:25:49ID:sskqg6P0
>>773
回答ありがとうございます。
やっぱパフォーマンスの問題になりますか…
0778nobodyさん04/12/20 21:25:58ID:???
>>776
ロックして書き込み中は読み込もうとしてもアクセスできないだろ。
0779nobodyさん04/12/20 22:28:54ID:???
>>776
追記モードでも、書き込み途中の中途半端なデータを読む可能性を考えればダメでは?
0780nobodyさん04/12/20 23:16:39ID:???
>>778 なこたぁない。。

>>779
そだね

けちろん: 読み込みデータがハンパでもいいタイプのシステムなら
ロックは無用。読み込みデータがその後のデータに関わってくるのなら
ロック白
0781nobodyさん04/12/20 23:47:40ID:???
>>778
ロックの掛け方による

>>779
例えば固定長なら書込み途中のデータを見分けて使わない機構とかできそうな予感がするな?

>>780
そのけつろんは読みの場合限定ってことで
■ このスレッドは過去ログ倉庫に格納されています