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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0609nobodyさん03/11/21 02:13ID:???
>>608
スレタイを何度も声を出してよく読んでから発言した方が良いのでは?
どう考えてもあなたのレスはどれもこのスレにはお呼びでないと思うのですが?
0610nobodyさん03/11/21 02:23ID:???
>>609 あーすまん。607はあんまり口だすつもりなかったんだが
このスレには、人のことを「ヘボ」としか言わないやつがいて
それがどうもしゃくに障ったんでな。Perlの話しなくてスマソ。
0611nobodyさん03/11/22 00:21ID:???
>>608
Webアプリなら自前でログ持つ、バグ対応すること考えれば当たり前。

「ソラリス」なんて呼ぶ奴が「OSのファイルロックはアトミックじゃないっす」といった時は
使い方間違ってる確率99.9999%
0612nobodyさん03/11/23 05:00ID:???
「そらりす」って読んでた(;´Д`)アヒャ
0613nobodyさん03/11/23 05:24ID:???
>>612
いや、その読み方で合ってるし。
0614nobodyさん03/11/23 05:41ID:???
ところでDBMSで使ってるロック機構ってのは具体的にどんな処理なんでしょうか
単純に思いつくのはキューですが・・・
やっぱデーモンみたいな別プロセスに一括一元管理させるのが安全っちゃ安全ですよね?
0615nobodyさん03/12/04 07:40ID:???
ここは進行遅いですね。

結局、実用に耐えるファイルロックはどれなのか
スクリプト例でまとめて欲しい。おねがいエロイヒト。
0616nobodyさん03/12/04 11:19ID:???
>>10,>>12
0617nobodyさん03/12/13 19:02ID:???
昨日新しいファイルロック法思いついたんだけど寝て起きたら忘れてた
0618nobodyさん03/12/13 19:54ID:???
21世紀のファイルロックなんだろうな?
0619nobodyさん03/12/15 12:22ID:???
WinFS は SQLserver ベースになるそうだから
ファイルロックなんだかDBロックなんだかわからんような
あやしげなロックが提供されるんじゃないのか
0620nobodyさん03/12/15 19:16ID:???
Windowsはレジストリロックが使えます。
排他処理中はキーが書き込まれます。
0621nobodyさん03/12/19 21:19ID:???
今まで、flockが使えないと思ってたんだが、実は使えた!
ってこと無いですか?
0622nobodyさん03/12/19 23:28ID:???
ありませんね
あぁ、知識が足りなくて自分は使えないと?
やっぱりありませんね
0623nobodyさん03/12/20 02:36ID:???
$fp = fopen("test.txt", "a+");
if(!flock($fp, LOCK_EX)) { fclose($fp); echo "ns"; }
echo "ok";
これでいい?
0624nobodyさん03/12/20 02:38ID:???
windows環境で使えないと思ったけど普通に使えることに気が付いてびっくり。
つーかヘルプに書いてあった。
0625nobodyさん03/12/21 05:04ID:FyNOPbG5
きょうび、自作Perlスクリプトを置けるのに、flockが使えないISPなりレンタルサーバなんて、あるの?
0626nobodyさん03/12/21 16:43ID:???
yahoo
0627nobodyさん04/01/08 00:54ID:???
NiftyとかIswebとか使えるけど掛かるかどうかは保証しないとか言ってなかったっけ。
多分既出の話。
0628nobodyさん04/01/18 18:15ID:???
俺も需要がなくなってしまった。
ブックマークから外してしまおうかな。。
0629nobodyさん04/01/18 19:34ID:???
ひととおりネタは出尽くしたからもう外していいと思うよ。
0630nobodyさん04/01/18 20:27ID:???
でも、技術や発想的には応用が利くというかあれなので勿体無い気もする。
いままでありがとう。
0631nobodyさん04/01/19 01:52ID:???
テンプレが見たいなぁ、でも2スレまでいかんだろうなぁ。
0632nobodyさん04/03/11 20:28ID:???
久しぶりに着ますた。dat落ちしてなくてよかた。

ネタが尽きたところで脱線したいんですが、
includeしたりするファイルはflockの必要が無いことを前提としているんですかね。

書き換えや追記などを行うファイルに対し、
includeやrequireしたりするのはナンセンスということで合ってますか?
0633nobodyさん04/03/12 15:23ID:???
それは…
実行するperlスクリプト本体にflockの必要があるか、という話と同じなんじゃないかと
0634nobodyさん04/03/12 15:32ID:???
perl コマンド本体に flock する必要はありますか?
0635nobodyさん04/03/12 23:11ID:???
そういやperlメインのスレですね。スマソ。

PHPにおけるincludeやrequireは単にプログラムの記述されたファイルだけでなく、
HTML、PHP複合型やtxtまで読み込めるわけです。
そういった意味での質問です。
0636nobodyさん04/03/14 16:47ID:???
>>424
歯痛か!
0637nobodyさん04/03/15 12:04ID:???
>>635
php でも perl SSI でも何でもいいんだけど、ロックが重要になるのは基本的に、
ファイルを書き換えるプロセスが複数存在して競合する場合、つまり

A:----->読み込み------->処理-------->書き出し---------------------
B:------------------->読み込み------->処理-------->書き出し-------

のようなケースね。
ロックしないとマジでファイルが壊れたり情報が失われたりする。

これに対して include や require って、
読み込みオンリーで書き換えが有り得ないという前提なので、
上記のような書き込みの競合に参加しないわけで、
そういう意味ではロックの必要性が薄い。
(全く必要性が無いわけじゃないが、ほとんどの場合無視できる)
0638nobodyさん04/03/15 16:15ID:???
共有ロックのLOCK_SHってのがあるんですが、
厳密に言えばロックの必要性があることを示しているんですよね。
0639nobodyさん04/03/15 16:44ID:???
ロック「してもいい」ってだけで、「必要」かというとそうでもないんじゃない?
0640nobodyさん04/03/15 16:44ID:???
ていうか、ロックしてみたところで、書き換えようと思えばできるわけで。
0641nobodyさん04/03/15 18:08ID:???
perl は最初に一括コンパイルするからいいけど、
sh ってスクリプトを一行読み込んで実行してを繰り返すから、
実行途中にスクリプトを書き換えると結構悲惨なことになったりするよな。
0642nobodyさん04/03/17 13:37ID:???
rename使ってファイルロックかけるモジュール作って大ハマリしました。
どうもOSによっては、ファイルシステムの情報取得にタイムラグがあるようで、
renameかけても、OSが保持するファイル情報が即座に更新されないために、
同じ元ファイル名からのrenameが成功してしまうことがありました。

より正確にrename形式でファイルロックをかけるには、
rename後に若干のタイムラグを置いて、rename後のファイルの存在チェックが通れば
ロック成功と考えた方がいいですね。

ちなみに、WinXP+NTFSの組み合わせでそれらの現象がありました。
Linuxだったりすると、こういう現象は出てきますでしょうか?
0643nobodyさん04/03/17 16:25ID:???
んなバカな。
何か間違っている。
0644nobodyさん04/03/17 18:02ID:???
>>642
君が作ったのを晒してくれないか
0645nobodyさん04/03/18 13:24ID:???
>>644
了解です。
ttp://www.mindcompass.sfcgi.com/misc/LOCK.pm.txt
0646nobodyさん04/03/19 13:53ID:???
とりあえずmkdirやrenameを実行した後
仕方なく-dや-eをしなさい。
064764204/03/19 16:28ID:???
>>646

その辺(ファイル操作後の存在チェック)は仕方なく実装してます。
同一プロセスで、同じファイルからのrenameコマンドを連続して実行すると、2回目は失敗(これが通常動作)するので、
他プロセスでのファイル操作の結果が反映されるのが遅いらしい。
0648nobodyさん04/03/19 16:33ID:???
-d or mkdirじゃなくてmkdir or !-d
0649nobodyさん04/03/29 10:00ID:WLF8C9h8
ログに「This is a test1.」と10万回書くCGIと「This is a test2.」と10万回書くCGIを二つ同時起動させてみた。
ログにはきちんと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:???
>>649
そもそも flock が使用不能なら呼び出した時点で実装されてないって怒られます。
実用的に使用可能か、という意味なら実際に試してみる価値があるかもしれません。
ただし、自分の想定している条件に近くないとあまり意味がないと思います。
0651nobodyさん04/03/31 01:14ID:???
子プロセスを10個forkしてプロセス一つで1000回カウンタを回すスクリプト使ってる。
perlで壊れないロックはflock()だけだった。
0652nobodyさん04/03/31 05:45ID:???
2chのロックはchmod()でやってるらしいね。
0653nobodyさん04/03/31 07:07ID:???
chmod()ではアトミックに書けないように思えるけど、
どんなんだろう。
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を使う手があるよん。名前にファイルパス(\は/に置き換えたやつ)
を使う。速いしいいぞ。
■ このスレッドは過去ログ倉庫に格納されています