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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0654nobodyさん04/03/31 12:43ID:???
chmod() でっていうのは具体的にどうやるの?
0655nobodyさん04/03/31 12:54ID:???
>>654
chmodがどういうものかわからないの?
0656nobodyさん04/03/31 13:50ID:???
時々書き込みしてもインデックスの数字が増えないことがあるが
ロックに失敗してると考えると納得できる話だな > 2chがchmodでロック
0657nobodyさん04/03/31 15:11ID:???
>>655
あなたはわかっているの?
0658nobodyさん04/03/31 18:13ID:???
運用情報のbbs.cgi再開発スレにチラッと載ってる。
0659nobodyさん04/03/31 21:42ID:???
>>658
1000ストップを確実にする方法の議論に見えました。
0660nobodyさん04/03/31 23:37ID:???
なんかflockを使いたくない議論してるよね。

どうせアトミックじゃないのなら
1000の書き込み後にchmodして
1001はクライアントで描画
dat落ち時にはdatに1001を書く、
とか適当にやれば1030くらいで止まるんじゃない?

ダサいけど。
0661nobodyさん04/04/10 18:40ID:???
余分な処理を追加して確実にするより1から書き直したほうがいいんじゃないかな。
運用の奴ら全員で1台のディスプレイを囲んで。
オンラインでの議論なんて無駄無駄。
0662nobodyさん04/04/16 01:00ID:???
filerock
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:???
renameするロックはうまく書けば完璧かなと思ったが、外からの干渉に弱い気がする。
0668nobodyさん04/04/26 01:31ID:???
干渉とは?
0669nobodyさん04/04/27 11:45ID:???
>>668
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:???
>>669
それは、前提が間違ってると思う。
「みなさん、ロックのためのリソースの○○はこうこうこういうふうに使いましょう」
っていう規約をみんながきちんと守ってる、っていう前提で設計しないと。
そんなこと言ったら、「ハカーが○○してきたら」とか「電源落されたら」とか
「スーパーユーザに○○されたら」とか考え出したら何もできないと思う。
0671nobodyさん04/04/27 13:54ID:???
>>670
ハァ?お前は K E N T か?
アップローダーを例に取るとサーバーとユーザーの設定次第で
http://pc5.2ch.net/test/read.cgi/hp/1076940865/888n
のような事も起こってしまうわけで。
専用のサーバーを使うなら>>670のような設計で構わないと思うけど、
こっちは共用向け、大量配布だからな。そういうわけにはいかんのよ。
0672nobodyさん04/04/27 14:22ID:???
>>671
「 K E N T 」というのは何だか知らないけど、そういうことなら納得です。

# でも >>667 のようなレスからそんな事情は推し測れないよ。
0673nobodyさん04/04/27 17:59ID:???
んー、でもやっぱ正しく安全に使える人が正しく安全に使える鯖で使って下さいで良い気がするんだけど。

初回起動時にランダムな文字列のディレクトリ名やファイル名をスクリプトが自分自身の中に保存して、
それを使い rename()(または mkdir() や open() で作成)してそれをベースとするとか。
ディレクトリ内の一覧表示とかに弱いし総当りもあるし完璧では無いけど。
0674nobodyさん04/04/27 18:00ID:???
と思ったが666なら外からスクリプト自体すら書き換え可能になるのか。
なんてこったい。
0675nobodyさん04/04/27 20:43ID:???
書き替えられるならやってみろ。外からな。
0676nobodyさん04/04/28 01:00ID:???
書き換えられないんなら良いんじゃない。
0677nobodyさん04/04/28 01:04ID:???
>>675
あんたのサイトの書き込み可能は無敵でうらやましいよ
0678nobodyさん04/04/28 01:51ID:???
結局ロックファイルとは直接関係ない話ね。
0679nobodyさん04/04/28 02:52ID:???
みんなさあ、自分の想定する環境とか前提条件とかを明確にしてから
話を始めるようにしようよ。
でないと議論にならないし不毛すぎるよ。

>>667 みたいな話の切り出し方は最低。
0680nobodyさん04/04/28 16:51ID:???
何だ何だ?renameをファイルロックに使ってる魚ばかり網にかかってるじゃないか。
0681nobodyさん04/04/28 17:14ID:???
みんなとほほに操られてるのね
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
■ このスレッドは過去ログ倉庫に格納されています