【Perl】ファイルロック(排他処理)について語ろう
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
02/06/23 10:18ID:eY2l+Gw10638nobodyさん
04/03/15 16:15ID:???厳密に言えばロックの必要性があることを示しているんですよね。
0639nobodyさん
04/03/15 16:44ID:???0640nobodyさん
04/03/15 16:44ID:???0641nobodyさん
04/03/15 18:08ID:???sh ってスクリプトを一行読み込んで実行してを繰り返すから、
実行途中にスクリプトを書き換えると結構悲惨なことになったりするよな。
0642nobodyさん
04/03/17 13:37ID:???どうもOSによっては、ファイルシステムの情報取得にタイムラグがあるようで、
renameかけても、OSが保持するファイル情報が即座に更新されないために、
同じ元ファイル名からのrenameが成功してしまうことがありました。
より正確にrename形式でファイルロックをかけるには、
rename後に若干のタイムラグを置いて、rename後のファイルの存在チェックが通れば
ロック成功と考えた方がいいですね。
ちなみに、WinXP+NTFSの組み合わせでそれらの現象がありました。
Linuxだったりすると、こういう現象は出てきますでしょうか?
0643nobodyさん
04/03/17 16:25ID:???何か間違っている。
0646nobodyさん
04/03/19 13:53ID:???仕方なく-dや-eをしなさい。
0647642
04/03/19 16:28ID:???その辺(ファイル操作後の存在チェック)は仕方なく実装してます。
同一プロセスで、同じファイルからのrenameコマンドを連続して実行すると、2回目は失敗(これが通常動作)するので、
他プロセスでのファイル操作の結果が反映されるのが遅いらしい。
0648nobodyさん
04/03/19 16:33ID:???0649nobodyさん
04/03/29 10:00ID:WLF8C9h8ログにはきちんと20万行書かれてた。
for ($i = 0; $i < 10000; $i++) {
open (DATA, ">>$file");
flock (DATA, 2);
print DATA $str;
close DATA;
}
こういうのじゃ、そのOSでflockが使用可能かって言う確認にはならないのですか?
ちなみに、環境はWin2KとActivePerl5.6.1で試しましたが。
0650nobodyさん
04/03/29 17:51ID:???そもそも flock が使用不能なら呼び出した時点で実装されてないって怒られます。
実用的に使用可能か、という意味なら実際に試してみる価値があるかもしれません。
ただし、自分の想定している条件に近くないとあまり意味がないと思います。
0651nobodyさん
04/03/31 01:14ID:???perlで壊れないロックはflock()だけだった。
0652nobodyさん
04/03/31 05:45ID:???0653nobodyさん
04/03/31 07:07ID:???どんなんだろう。
0654nobodyさん
04/03/31 12:43ID:???0656nobodyさん
04/03/31 13:50ID:???ロックに失敗してると考えると納得できる話だな > 2chがchmodでロック
0658nobodyさん
04/03/31 18:13ID:???0660nobodyさん
04/03/31 23:37ID:???どうせアトミックじゃないのなら
1000の書き込み後にchmodして
1001はクライアントで描画
dat落ち時にはdatに1001を書く、
とか適当にやれば1030くらいで止まるんじゃない?
ダサいけど。
0661nobodyさん
04/04/10 18:40ID:???運用の奴ら全員で1台のディスプレイを囲んで。
オンラインでの議論なんて無駄無駄。
0662nobodyさん
04/04/16 01:00ID:???0663nobodyさん
04/04/19 09:45ID:???ロックファイルをファイルロックしなければならなくなった。orz
0664nobodyさん
04/04/21 07:50ID:???0665nobodyさん
04/04/21 12:24ID:???よくある流行歌の「君がいるだけで」というフレーズが言い当てています。
0666nobodyさん
04/04/23 14:39ID:???0667nobodyさん
04/04/26 01:30ID:???0668nobodyさん
04/04/26 01:31ID:???0669nobodyさん
04/04/27 11:45ID:???1分でレスしてきた君のためにGTO神書き換えのレスで返そうかと思ったけど、難しいのでやめた。
例えば、/path/to/dataというパスのファイルをファイルロック中は/path/to/data.lockとするぷろぐらみゅがあるとして、
その横で
while(1) {
open(F, '>/path/to/data');
close(F);
open(F, '>/path/to/data.lock');
close(F);
}
なんてことされたらたまんねぇと。
まあ、適切にパーミッションを設定すれば問題ないのだが、
私はファイルは0666、ディレクトリは0777でも問題ないことを信条としてるのであれかなと。
0670nobodyさん
04/04/27 13:29ID:???それは、前提が間違ってると思う。
「みなさん、ロックのためのリソースの○○はこうこうこういうふうに使いましょう」
っていう規約をみんながきちんと守ってる、っていう前提で設計しないと。
そんなこと言ったら、「ハカーが○○してきたら」とか「電源落されたら」とか
「スーパーユーザに○○されたら」とか考え出したら何もできないと思う。
0671nobodyさん
04/04/27 13:54ID:???ハァ?お前は K E N T か?
アップローダーを例に取るとサーバーとユーザーの設定次第で
http://pc5.2ch.net/test/read.cgi/hp/1076940865/888n
のような事も起こってしまうわけで。
専用のサーバーを使うなら>>670のような設計で構わないと思うけど、
こっちは共用向け、大量配布だからな。そういうわけにはいかんのよ。
0672nobodyさん
04/04/27 14:22ID:???「 K E N T 」というのは何だか知らないけど、そういうことなら納得です。
# でも >>667 のようなレスからそんな事情は推し測れないよ。
0673nobodyさん
04/04/27 17:59ID:???初回起動時にランダムな文字列のディレクトリ名やファイル名をスクリプトが自分自身の中に保存して、
それを使い rename()(または mkdir() や open() で作成)してそれをベースとするとか。
ディレクトリ内の一覧表示とかに弱いし総当りもあるし完璧では無いけど。
0674nobodyさん
04/04/27 18:00ID:???なんてこったい。
0675nobodyさん
04/04/27 20:43ID:???0676nobodyさん
04/04/28 01:00ID:???0678nobodyさん
04/04/28 01:51ID:???0679nobodyさん
04/04/28 02:52ID:???話を始めるようにしようよ。
でないと議論にならないし不毛すぎるよ。
>>667 みたいな話の切り出し方は最低。
0680nobodyさん
04/04/28 16:51ID:???0681nobodyさん
04/04/28 17:14ID:???0682nobodyさん
04/04/30 17:27ID:???そんな物を使うぐらいならソケットでプロセス間通信をしてしまう方が楽であると思うが、
Perlなんかでそんな事したらパフォーマンスが(以下略
0683nobodyさん
04/05/19 04:13ID:???誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。
それが嫌な場合は
open(DATA,"< test.txt");
flock(DATA,1);
なんたらかんたら
close(DATA);
みたいにして一人がオープンしている間は別プロセスには待たせればよろしいんでしょうか?
flockの説明を見てみると読みこみだけの時用の番号がなかったので、不安です。自分のPCはwin98なのでflockは使えませんし、
鯖にぶつけ本番はいやだなと思って聞きにきました。
0685nobodyさん
04/05/19 07:03ID:???書き込みの処理が2つ以上同時に行われないと分かっている場合
かつ、一過性の読み込み失敗を許容する場合
書き込みにロックは不要ですか?
0686nobodyさん
04/05/19 09:38ID:4B5lUTgr話はそれからだ
0688683
04/05/19 17:00ID:???いらないんですか。ということはアクセス集中によるオープンエラーは読みこみだけならば
起こらないということですか?
本当は自分でその状況を作り出してテストしてみたいんですけど、動作テストはwin98に入れたhttpdなので
同時アクセスが試せないんですよね。
ファイルオープンするCGIがユーザに色んな項目を記入してもらった次のページなのでエラーが
でちゃうとまた、入力してもらう事になってしまうのでそれはまずいなと思いまして;
0689nobodyさん
04/05/19 18:15ID:???これがそもそも勘違いだしな。
0690nobodyさん
04/05/19 19:43ID:???Windows はどうだか知らんけど、
UNIX なら読み出すだけならアクセス集中でオープンエラーなんてないだろ。
つーか、そこまで信頼性高いシステムが必要なら、2ちゃんなんかで質問するより、
もっとちゃんと調べて勉強するか、外注に出した方が良いんじゃないか?
0691683
04/05/19 23:00ID:???ありがとうございます。
吐いた制御ってオープンエラーを防ぐんじゃなくて、書きこみが同時に行われてファイルが壊れるのを
防ぐためにあるってことですね。
>>690
ありがとうございました。
0692685
04/05/20 15:35ID:???返答ありがとうございます。
>>686
Dirty readとは書き込み中に読み込めるということで、最新でないものを読み込めてしまうということでしょうか。
それは構いませんし、リロードで直る一時的なものであれば読み取りが0バイトでも構いません。
>>687
そういう事になるかも知れません。
言い換えると
書き込み処理が重複しない時、理論的にファイルが壊れるか否かが知りたいのです。
0693nobodyさん
04/05/20 20:28ID:???その中でも「書き込み処理が重複する」という原因はよく起こる。
この重複を避けるための道具が、ファイルロック。
ロックは、これさえかければファイルが壊れなくなるという魔法の杖ではない。
ロックは単なるプログラミングの道具に過ぎず、
それも、ファイルを壊さなくするための道具ではなく、
書き込みが重複しているかどうかを識別するだけの道具。
識別した上で書き込みが重複しないようにプログラムを書くのは、プログラマの責任。
逆に、書き込みが重複しないということが100%保証されているなら、
ロックをかけてもかけなくても変わらない。
もちろんその場合でも、書き込み処理重複以外の原因でファイルが壊れることは、いくらでも考えられる。
0694nobodyさん
04/05/20 20:38ID:???保証する方法なんてあるのか?
0695nobodyさん
04/05/20 21:07ID:???まではいい事言ってると思うんだが最後の方になって壊れてるな。
0696nobodyさん
04/05/20 22:40ID:???単に、書き込みが100%重複しない論理空間を仮定すれば、というだけの話でしょ。
もちろん現実にそんなことはありえないと暗示しているわけで。
0697685
04/05/21 01:02ID:???>>693
という事は書き込みが重複しないなら、
ファイルロックで防げる程度のトラブルは防げるという事ですね。
>>694
書き込み処理を行えるのがパスワードを知っている1人なのです。
パスワードが他人に漏れず、その1人が同時に操作せず、
openしたまま処理が中断することもない・・・
という仮定はありますが。
ファルイロックの基本的な知識さえない私に丁寧な回答ありがとうございました。
0698nobodyさん
04/05/27 13:48ID:???けっこうウソ書いてあるサイトが多いのに驚いた。
0700nobodyさん
04/05/27 20:14ID:???0701nobodyさん
04/05/27 21:10ID:???0702nobodyさん
04/05/27 21:08ID:???0703nobodyさん
04/05/28 01:38ID:???見せてよ
0704698
04/05/28 11:16ID:???自分で掴み取れ! これに尽きるな
0705nobodyさん
04/05/28 15:29ID:???0706nobodyさん
04/05/30 14:43ID:???0708nobodyさん
04/05/30 18:12ID:???0709nobodyさん
04/05/30 22:14ID:???を使う。速いしいいぞ。
0710709
04/05/30 22:16ID:???xs使って作るしか、、、。
0711nobodyさん
04/05/30 22:23ID:???http://search.cpan.org/~gsar/libwin32-0.191/
0712nobodyさん
04/05/31 00:08ID:???他のOSとかもないのかな。
lock::mutexとかいう一本にまとめて使えるようなライブラリがいいなぁ。
mutexもセマフォも使えないけどflockは使えるOSだったら、
内部実装はflockでやるとか。
0713357
04/05/31 20:57ID:???0714713
04/05/31 22:53ID:???0715nobodyさん
04/10/09 22:28:45ID:???タアソウスルナラ イマノウチ
0716nobodyさん
04/10/09 23:12:22ID:???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++;
でいいと思うけど。
0720nobodyさん
04/10/10 17:10:11ID:???open (IN, "count.dat");
flock(IN,2);
$count=<IN>;
$count++;
print IN $count;
close(IN);
これでいいじゃん
0721716
04/10/10 17:16:22ID:???0722nobodyさん
04/10/10 17:19:40ID:???open (IN, "+>count.dat");
0723716
04/10/10 17:36:23ID:???0724nobodyさん
04/10/10 17:43:35ID:???そんなのは一概には言えない。
各ファイルは読み込み・書き込み・両方のいずれなのか、
一度に連続して読み書きするのかなど。
0725nobodyさん
04/10/20 14:16:48ID:ejI/DpjA0726nobodyさん
04/10/21 19:09:46ID:wxBAgdgRmkdirとかにしといた方が無難かね?
それぞれでflock()したって排他かからない?
0727nobodyさん
04/10/21 19:24:18ID:???0728nobodyさん
04/10/21 23:27:35ID:???デマ飛ばすな。ボケッ
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なるほど、結局perl,phpのflock()が同じシステムコールを使うかどうかって所ですかね?
linux(redhat)なんですが、普通にflock(2)使ってると思って良いのかなぁ。
0730nobodyさん
04/10/22 17:20:32ID:???0731nobodyさん
04/10/23 01:59:39ID:???php4.3.9/linux はソース確認したところ flock(2) 使ってないよ。fcntl(2)。
0732nobodyさん
04/10/23 02:53:34ID:???0733nobodyさん
04/10/23 04:34:45ID:???双方とも 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:???0737nobodyさん
04/11/06 19:49:00ID:em3fuQlS■ このスレッドは過去ログ倉庫に格納されています