1 名前:nobodyさん [02/06/23 10:18 ID:eY2l+Gw1] どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
655 名前:nobodyさん mailto:sage [04/03/31 12:54 ID:???] >>654 chmodがどういうものかわからないの?
656 名前:nobodyさん mailto:sage [04/03/31 13:50 ID:???] 時々書き込みしてもインデックスの数字が増えないことがあるが ロックに失敗してると考えると納得できる話だな > 2chがchmodでロック
657 名前:nobodyさん mailto:sage [04/03/31 15:11 ID:???] >>655 あなたはわかっているの?
658 名前:nobodyさん mailto:sage [04/03/31 18:13 ID:???] 運用情報のbbs.cgi再開発スレにチラッと載ってる。
659 名前:nobodyさん mailto:sage [04/03/31 21:42 ID:???] >>658 1000ストップを確実にする方法の議論に見えました。
660 名前:nobodyさん mailto:sage [04/03/31 23:37 ID:???] なんかflockを使いたくない議論してるよね。 どうせアトミックじゃないのなら 1000の書き込み後にchmodして 1001はクライアントで描画 dat落ち時にはdatに1001を書く、 とか適当にやれば1030くらいで止まるんじゃない? ダサいけど。
661 名前:nobodyさん mailto:sage [04/04/10 18:40 ID:???] 余分な処理を追加して確実にするより1から書き直したほうがいいんじゃないかな。 運用の奴ら全員で1台のディスプレイを囲んで。 オンラインでの議論なんて無駄無駄。
662 名前:nobodyさん mailto:sage [04/04/16 01:00 ID:???] filerock
663 名前:nobodyさん mailto:sage [04/04/19 09:45 ID:???] ロック状態の情報をロックファイルの中に書いておこうと思ったら、 ロックファイルをファイルロックしなければならなくなった。orz
664 名前:nobodyさん mailto:sage [04/04/21 07:50 ID:???] ロックファイルをファイルロックした情報をロックファイルに書くことはしないんでしょう。
665 名前:nobodyさん mailto:sage [04/04/21 12:24 ID:???] ロックファイルは存在が全てです。 よくある流行歌の「君がいるだけで」というフレーズが言い当てています。
666 名前:nobodyさん mailto:sage [04/04/23 14:39 ID:???] たとえばーきみがいるだーけでこころがーろっくされるーことー
667 名前:nobodyさん mailto:sage [04/04/26 01:30 ID:???] renameするロックはうまく書けば完璧かなと思ったが、外からの干渉に弱い気がする。
668 名前:nobodyさん mailto:sage [04/04/26 01:31 ID:???] 干渉とは?
669 名前:nobodyさん mailto:sage [04/04/27 11:45 ID:???] >>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でも問題ないことを信条としてるのであれかなと。
670 名前:nobodyさん mailto:sage [04/04/27 13:29 ID:???] >>669 それは、前提が間違ってると思う。 「みなさん、ロックのためのリソースの○○はこうこうこういうふうに使いましょう」 っていう規約をみんながきちんと守ってる、っていう前提で設計しないと。 そんなこと言ったら、「ハカーが○○してきたら」とか「電源落されたら」とか 「スーパーユーザに○○されたら」とか考え出したら何もできないと思う。
671 名前:nobodyさん mailto:sage [04/04/27 13:54 ID:???] >>670 ハァ?お前は K E N T か? アップローダーを例に取るとサーバーとユーザーの設定次第で pc5.2ch.net/test/read.cgi/hp/1076940865/888n のような事も起こってしまうわけで。 専用のサーバーを使うなら>>670 のような設計で構わないと思うけど、 こっちは共用向け、大量配布だからな。そういうわけにはいかんのよ。
672 名前:nobodyさん mailto:sage [04/04/27 14:22 ID:???] >>671 「 K E N T 」というのは何だか知らないけど、そういうことなら納得です。 # でも >>667 のようなレスからそんな事情は推し測れないよ。
673 名前:nobodyさん mailto:sage [04/04/27 17:59 ID:???] んー、でもやっぱ正しく安全に使える人が正しく安全に使える鯖で使って下さいで良い気がするんだけど。 初回起動時にランダムな文字列のディレクトリ名やファイル名をスクリプトが自分自身の中に保存して、 それを使い rename()(または mkdir() や open() で作成)してそれをベースとするとか。 ディレクトリ内の一覧表示とかに弱いし総当りもあるし完璧では無いけど。
674 名前:nobodyさん mailto:sage [04/04/27 18:00 ID:???] と思ったが666なら外からスクリプト自体すら書き換え可能になるのか。 なんてこったい。
675 名前:nobodyさん mailto:sage [04/04/27 20:43 ID:???] 書き替えられるならやってみろ。外からな。
676 名前:nobodyさん mailto:sage [04/04/28 01:00 ID:???] 書き換えられないんなら良いんじゃない。
677 名前:nobodyさん mailto:sage [04/04/28 01:04 ID:???] >>675 あんたのサイトの書き込み可能は無敵でうらやましいよ
678 名前:nobodyさん mailto:sage [04/04/28 01:51 ID:???] 結局ロックファイルとは直接関係ない話ね。
679 名前:nobodyさん mailto:sage [04/04/28 02:52 ID:???] みんなさあ、自分の想定する環境とか前提条件とかを明確にしてから 話を始めるようにしようよ。 でないと議論にならないし不毛すぎるよ。 >>667 みたいな話の切り出し方は最低。
680 名前:nobodyさん mailto:sage [04/04/28 16:51 ID:???] 何だ何だ?renameをファイルロックに使ってる魚ばかり網にかかってるじゃないか。
681 名前:nobodyさん mailto:sage [04/04/28 17:14 ID:???] みんなとほほに操られてるのね
682 名前:nobodyさん mailto:sage [04/04/30 17:27 ID:???] という事で、bindでロックをかけようとしたが、Windows(Me)上ではいくらでもbind出来てしまうので意味無し。 そんな物を使うぐらいならソケットでプロセス間通信をしてしまう方が楽であると思うが、 Perlなんかでそんな事したらパフォーマンスが(以下略
683 名前:nobodyさん mailto:sage [04/05/19 04:13 ID:???] すいません。PERLのCGIでtxtファイルを読みこむんですが、読みこみだけの場合でも排他制御は必要でしょうか? 誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。 それが嫌な場合は open(DATA,"< test.txt"); flock(DATA,1); なんたらかんたら close(DATA); みたいにして一人がオープンしている間は別プロセスには待たせればよろしいんでしょうか? flockの説明を見てみると読みこみだけの時用の番号がなかったので、不安です。自分のPCはwin98なのでflockは使えませんし、 鯖にぶつけ本番はいやだなと思って聞きにきました。
684 名前:nobodyさん mailto:sage [04/05/19 04:50 ID:???] >>683 みんな読むだけだったら別に排他制御は全然要らんよ。
685 名前:nobodyさん mailto:sage [04/05/19 07:03 ID:???] 683氏に似た質問です。 書き込みの処理が2つ以上同時に行われないと分かっている場合 かつ、一過性の読み込み失敗を許容する場合 書き込みにロックは不要ですか?
686 名前:nobodyさん [04/05/19 09:38 ID:4B5lUTgr] Dirty readを許すのか、許さないのか? 話はそれからだ
687 名前:nobodyさん mailto:sage [04/05/19 11:10 ID:???] >>685 「ロックとは何のために必要なのかを教えてくれ」という質問と等価と考えてよいのかな
688 名前:683 mailto:sage [04/05/19 17:00 ID:???] >>684 いらないんですか。ということはアクセス集中によるオープンエラーは読みこみだけならば 起こらないということですか? 本当は自分でその状況を作り出してテストしてみたいんですけど、動作テストはwin98に入れたhttpdなので 同時アクセスが試せないんですよね。 ファイルオープンするCGIがユーザに色んな項目を記入してもらった次のページなのでエラーが でちゃうとまた、入力してもらう事になってしまうのでそれはまずいなと思いまして;
689 名前:nobodyさん mailto:sage [04/05/19 18:15 ID:???] >誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。 これがそもそも勘違いだしな。
690 名前:nobodyさん mailto:sage [04/05/19 19:43 ID:???] >>688 Windows はどうだか知らんけど、 UNIX なら読み出すだけならアクセス集中でオープンエラーなんてないだろ。 つーか、そこまで信頼性高いシステムが必要なら、2ちゃんなんかで質問するより、 もっとちゃんと調べて勉強するか、外注に出した方が良いんじゃないか?
691 名前:683 mailto:sage [04/05/19 23:00 ID:???] >>689 ありがとうございます。 吐いた制御ってオープンエラーを防ぐんじゃなくて、書きこみが同時に行われてファイルが壊れるのを 防ぐためにあるってことですね。 >>690 ありがとうございました。
692 名前:685 mailto:sage [04/05/20 15:35 ID:???] >685です。レスが遅れてすみません。 返答ありがとうございます。 >>686 Dirty readとは書き込み中に読み込めるということで、最新でないものを読み込めてしまうということでしょうか。 それは構いませんし、リロードで直る一時的なものであれば読み取りが0バイトでも構いません。 >>687 そういう事になるかも知れません。 言い換えると 書き込み処理が重複しない時、理論的にファイルが壊れるか否かが知りたいのです。
693 名前:nobodyさん mailto:sage [04/05/20 20:28 ID:???] ファイルを壊す原因は山ほどあるが、 その中でも「書き込み処理が重複する」という原因はよく起こる。 この重複を避けるための道具が、ファイルロック。 ロックは、これさえかければファイルが壊れなくなるという魔法の杖ではない。 ロックは単なるプログラミングの道具に過ぎず、 それも、ファイルを壊さなくするための道具ではなく、 書き込みが重複しているかどうかを識別するだけの道具。 識別した上で書き込みが重複しないようにプログラムを書くのは、プログラマの責任。 逆に、書き込みが重複しないということが100%保証されているなら、 ロックをかけてもかけなくても変わらない。 もちろんその場合でも、書き込み処理重複以外の原因でファイルが壊れることは、いくらでも考えられる。
694 名前:nobodyさん mailto:sage [04/05/20 20:38 ID:???] 書き込みが重複しないということをロック以外の方法で100%に近い精度で 保証する方法なんてあるのか?
695 名前:nobodyさん mailto:sage [04/05/20 21:07 ID:???] >〜するだけの道具。 まではいい事言ってると思うんだが最後の方になって壊れてるな。
696 名前:nobodyさん mailto:sage [04/05/20 22:40 ID:???] >>694 単に、書き込みが100%重複しない論理空間を仮定すれば、というだけの話でしょ。 もちろん現実にそんなことはありえないと暗示しているわけで。
697 名前:685 mailto:sage [04/05/21 01:02 ID:???] 皆様回答ありがとうございます。 >>693 という事は書き込みが重複しないなら、 ファイルロックで防げる程度のトラブルは防げるという事ですね。 >>694 書き込み処理を行えるのがパスワードを知っている1人なのです。 パスワードが他人に漏れず、その1人が同時に操作せず、 openしたまま処理が中断することもない・・・ という仮定はありますが。 ファルイロックの基本的な知識さえない私に丁寧な回答ありがとうございました。
698 名前:nobodyさん mailto:sage [04/05/27 13:48 ID:???] やっと最近になってきっちりしたファイルロックのコード書けるようになった。 けっこうウソ書いてあるサイトが多いのに驚いた。
699 名前:nobodyさん mailto:sage [04/05/27 17:15 ID:???] >>698 そういうサイトもきっちり書けていると思ってんだろ。 お前と同じように。
700 名前:nobodyさん mailto:sage [04/05/27 20:14 ID:???] きっちり書けるようになったと自分で思い込むのは勝手だが、他人には言うな。
701 名前:nobodyさん mailto:sage [04/05/27 21:10 ID:???] どうキッチリ書いたか教えて欲しい
702 名前:nobodyさん mailto:sage [04/05/27 21:08 ID:???] どう書いたか教えて欲しい
703 名前:nobodyさん mailto:期待上げ [04/05/28 01:38 ID:???] うん 見せてよ
704 名前:698 mailto:sage [04/05/28 11:16 ID:???] わたしは秘密主義なんで弟子にも教えることはない。 自分で掴み取れ! これに尽きるな
705 名前:nobodyさん mailto:sage [04/05/28 15:29 ID:???] ふっ。これで糞コード蔓延の芽がまた一つ摘み取られた。良かった良かった。
706 名前:nobodyさん mailto:sage [04/05/30 14:43 ID:???] ファイルロックなんかしなくったって、めっちゃ速く処理してしまえばええやん
707 名前:nobodyさん mailto:sage [04/05/30 14:44 ID:???] >>706 すげー!! それだっ!
708 名前:nobodyさん mailto:age [04/05/30 18:12 ID:???] ファイルロックなんかしなくったって、誰もアクセスしなければええやん
709 名前:nobodyさん mailto:sage [04/05/30 22:14 ID:???] windowsならmutexを使う手があるよん。名前にファイルパス(\は/に置き換えたやつ) を使う。速いしいいぞ。
710 名前:709 mailto:sage [04/05/30 22:16 ID:???] はっ、ここはPerlの板だった。 xs使って作るしか、、、。
711 名前:nobodyさん mailto:sage [04/05/30 22:23 ID:???] >>709 Win32::Mutex search.cpan.org/~gsar/libwin32-0.191/
712 名前:nobodyさん mailto:sage [04/05/31 00:08 ID:???] おお、あるんだ。 他のOSとかもないのかな。 lock::mutexとかいう一本にまとめて使えるようなライブラリがいいなぁ。 mutexもセマフォも使えないけどflockは使えるOSだったら、 内部実装はflockでやるとか。
713 名前:357 mailto:sage [04/05/31 20:57 ID:???] flock使えない機種でmutexを使ってflock模擬したほうがいいか。
714 名前:713 mailto:sage [04/05/31 22:53 ID:???] うわ、名前間違えた。
715 名前:nobodyさん mailto:age [04/10/09 22:28:45 ID:???] ダレモイナィ タアソウスルナラ イマノウチ
716 名前:nobodyさん mailto:sage [04/10/09 23:12:22 ID:???] 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?
717 名前:nobodyさん mailto:sage [04/10/10 04:46:13 ID:???] 萌えは初心者だから良くわからないけど、 $count=$count++; は $count++; でいいと思うけど。
718 名前:nobodyさん mailto:sage [04/10/10 16:53:04 ID:???] >>716 いいえNG
719 名前:716 mailto:sage [04/10/10 16:59:43 ID:???] >>718 どこら辺がNG?
720 名前:nobodyさん mailto:sage [04/10/10 17:10:11 ID:???] 無駄なことをやってるだけだろ open (IN, "count.dat"); flock(IN,2); $count=<IN>; $count++; print IN $count; close(IN); これでいいじゃん
721 名前:716 mailto:sage [04/10/10 17:16:22 ID:???] えっ?それじゃ書き込めないのでは?
722 名前:nobodyさん mailto:sage [04/10/10 17:19:40 ID:???] すまん open (IN, "+>count.dat");
723 名前:716 mailto:sage [04/10/10 17:36:23 ID:???] カウンタだとそれでいいけど、掲示板など複数のファイルを弄る場合にはロック用のファイルが必要になるよね?
724 名前:nobodyさん mailto:sage [04/10/10 17:43:35 ID:???] >>723 そんなのは一概には言えない。 各ファイルは読み込み・書き込み・両方のいずれなのか、 一度に連続して読み書きするのかなど。
725 名前:nobodyさん [04/10/20 14:16:48 ID:ejI/DpjA] aaa
726 名前:nobodyさん [04/10/21 19:09:46 ID:wxBAgdgR] perl,phpの両スクリプトから書き込みがあるファイルがあるんだが、 mkdirとかにしといた方が無難かね? それぞれでflock()したって排他かからない?
727 名前:nobodyさん mailto:sage [04/10/21 19:24:18 ID:???] 実装言語がどれでも中では flock(2) を呼ぶわけだし flock() で問題ないんじゃない?
728 名前:nobodyさん mailto:sage [04/10/21 23:27:35 ID:???] >>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.
729 名前:nobodyさん [04/10/22 01:27:00 ID:W+TTmfbF] >>727 なるほど、結局perl,phpのflock()が同じシステムコールを使うかどうかって所ですかね? linux(redhat)なんですが、普通にflock(2)使ってると思って良いのかなぁ。
730 名前:nobodyさん mailto: [04/10/22 17:20:32 ID:???] 通常、perlのflock()もphpのflock()も、下位レベルで使ってるシステムコールはflock(2)なわけだが。
731 名前:nobodyさん mailto:sage [04/10/23 01:59:39 ID:???] 言語, OS, ファイルシステム等の実装に依存 php4.3.9/linux はソース確認したところ flock(2) 使ってないよ。fcntl(2)。
732 名前:nobodyさん mailto:sage [04/10/23 02:53:34 ID:???] perl5.8/linuxはflock(2)だっけ?fcntl(2)だったっけ?
733 名前:nobodyさん mailto:sage [04/10/23 04:34:45 ID:???] ごめん、phpでもflock(2)使ってた. -->731は間違い 双方とも flock(2) が使える環境では flock が使われる. また間違ってるかも知れないので、調べたソースを書いておく。 php-4.3.9 ./ext/standard/flock_compat.c perl-5.8.5 ./pp_sys.c
734 名前:nobodyさん mailto:sage [04/10/23 13:22:56 ID:???] おお、すばらしい。 flock(2)使える環境って前提になるが(BSD,SystemV,Linux?)、PerlでもPHPでもflock()でいけるのか。 NFS上のディスクは別として。
735 名前:nobodyさん mailto:sage [04/10/25 18:24:04 ID:???] なるほどねぇ
736 名前:nobodyさん mailto: [04/10/25 19:07:12 ID:???] lockアゲ
737 名前:nobodyさん [04/11/06 19:49:00 ID:em3fuQlS]
738 名前:nobodyさん mailto:sage [04/11/06 19:58:00 ID:???] flock最強神話
739 名前:nobodyさん mailto:sage [04/11/07 05:49:26 ID:???] RDBMSで行ロック最強
740 名前:nobodyさん mailto:sage [04/11/07 23:08:21 ID:???] 結局、KENTのmkdirやsymlink、初心者のよく使うflock、どこかでみたrename、格付けするとどうなの?
741 名前:nobodyさん mailto:sage [04/11/08 00:05:16 ID:???] >>740 格付けなんて意味ないのでは?適材適所でしょ。
742 名前:nobodyさん mailto:sage [04/11/08 00:10:15 ID:???] >>740 flockを使う奴は素人だといいたいのか〜(w
743 名前:nobodyさん mailto:sage [04/11/08 00:30:26 ID:???] >>740 KENTは素人じゃないといいたいのか〜(w
744 名前:nobodyさん [04/11/08 13:12:26 ID:BIj8xOyZ] 最終兵器ロックオン・レーザー搭載! 「一度捕まえたら、離さない・・・・・」 TAITOの名作シューティングRAY・FORCEができるのは セガサターンだけ!
745 名前:740 mailto:sagePerl歴4ヵ月PHP歴28日 [04/11/08 21:24:24 ID:???] いや…そういう訳じゃ…
746 名前:nobodyさん mailto:sage [04/11/08 23:46:08 ID:???] cmpxchg最強
747 名前:nobodyさん mailto:sage [04/11/09 03:55:57 ID:???] >>744 レイヤーセクションじゃなかったっけ?
748 名前:nobodyさん mailto:sage [04/11/09 07:25:54 ID:???] >>740 flock>>>>>越えられない壁>>>>>rename=symlink>>mkdir
749 名前:nobodyさん mailto:sage [04/11/09 08:59:34 ID:???] flockはNFS介して使うと壊れるから糞
750 名前:nobodyさん mailto:sage [04/11/09 13:16:33 ID:???] 激しくループしてるな。
751 名前:nobodyさん mailto:sage [04/11/09 13:43:34 ID:???] ネタがファイルロックだけだから進展しようが無い
752 名前:nobodyさん mailto:sage [04/11/09 20:07:15 ID:???] >>749 NFSを使った事無いので、良く分からないので教えてください。 NFSを利用する時はflock関数にflock(2)ではなくfcntl(2)を利用するように perlをビルドすると思いますが、それでもロックは壊れるのでしょうか。 fcntl(2)で壊れる場合、実際の解決手段として、どのようなものがあるのでしょうか。
753 名前:nobodyさん mailto:sage [04/11/10 00:42:16 ID:???] >>752 Maildir
754 名前:nobodyさん mailto:sage [04/11/10 01:28:10 ID:???] >>753 djb 厨ってホントにいつも頭使わずに発言するなあ。
755 名前:nobodyさん mailto:sage [04/11/10 21:25:46 ID:???] >>753 それは、ロック機構が無くても信頼できるメールボックスの話だと思うのですが、 一般的なファイルアクセスにも使えるのでしょうか。
756 名前:nobodyさん [04/11/12 07:07:11 ID:djvAfFkI] >>747 レイフォース >>>> 越えられない壁 >>>> レイヤーセクション
757 名前:752 mailto:sage [04/11/13 13:06:05 ID:???] 調べてみたところ、 ・NFS Version4なら、ロック機構が組み込まれているので問題が無い(flock(2)でok?) ・NLM(Network Lock Manager)プロトコルに対応したサーバとクライアントならば、 fcntl(2)で対応可能。(ただし、一部のシステムで信頼が無いかも) ・それ以外はロックファイルを作るのが一般的 という感じらしいことが分かりました。 ありがとうございました。
758 名前:nobodyさん [04/11/13 15:51:42 ID:6imth/Ie] >756 レイストーム >>> レイフォース >>> レイクライシス
759 名前:nobodyさん mailto:sage [04/11/14 12:08:06 ID:???] レイフォース=ガンロック >> php >> perl >> レイヤーセクション >> レイストーム / レイクライシス
760 名前:nobodyさん mailto:sage [04/11/15 01:32:31 ID:???] なんか、SIMPLE1500のTHEダブルシューティングが欲しくなってきたw
761 名前:nobodyさん [04/11/18 09:27:07 ID:upfr9/ei] >>760 それなに?
762 名前:nobodyさん [04/11/18 10:10:24 ID:3NzX+MnA] 俺もレイ・フォースは好きだったな 懐かしい
763 名前:nobodyさん [04/11/18 19:52:46 ID:GLzLqJbZ] >>762 同意。
764 名前:nobodyさん mailto:sage [04/11/18 20:49:35 ID:???] おめーらロックすんぞ
765 名前:nobodyさん [04/11/27 15:36:14 ID:o5xdYnQz] ファイルロックって読み込むときは必要無いの?
766 名前:nobodyさん mailto:sage [04/11/27 15:54:59 ID:???] ロックするべ?
767 名前:nobodyさん mailto:sage [04/11/27 17:40:53 ID:???] >>765 書き込みが行われず中身が固定のファイルなら不要
768 名前:nobodyさん mailto:sage [04/12/04 12:35:02 ID:???] 質問しに来たらすでに同じ質問してる人がいた。 >>765-767 サンクス 過去ログは見るもんだ。
769 名前:nobodyさん mailto:sage [04/12/04 19:37:01 ID:???] それは過去ログって言わないけどな
770 名前:nobodyさん mailto:sage [04/12/20 07:41:20 ID:???] 追記モードのやつを読むときはいらないんじゃないの? 壊れてる可能性のあるところってバッティングしているときのだけでしょ?
771 名前:nobodyさん [04/12/20 14:13:21 ID:sskqg6P0] phpとperlでflock関数でファイルロックをしてますが 現在1つのスクリプト中に複数の箇所でファイルロックを使ってます。 これらのファイルロックを全てやめて代わりに、 スクリプトの一番最初でダミーのファイルにロックをかけて スクリプトの一番最後でロックを解除するようにして他のプロセスが スクリプトを実行しているときはスクリプトの実行自体を順番待ちさせて 同時に複数のプロセスがファイルへの書き込みをできないように 変えようと思いますが、何か問題あるでしょうか? 1つ気になるのは、もしスクリプトの途中でexit関数等でスクリプトの実行が終了した場合は 自動的にダミーファイルのロックが解除されファイルも自動的にcloseされますか?
772 名前:nobodyさん mailto:sage [04/12/20 15:14:56 ID:???] >>770 追記であろうがなかろうが書き込みはロックした上で行われるのなら 読み込みだけのときはロック不要。
773 名前:nobodyさん mailto:sage [04/12/20 15:30:20 ID:???] >>771 プロセスが死ねばロックは解除される。 先頭と末尾でロックと解除をするようにするのはいいが、 パフォーマンス低下は明らか。
774 名前:nobodyさん mailto:sage [04/12/20 16:09:04 ID:???] mod_perl や mod_php のときって スクリプトの実行が終了してもプロセスは死なないと思うけど mod_* がスクリプト中の flock の後始末を面倒見てくれるんですよね?
775 名前:nobodyさん mailto:sage [04/12/20 20:09:18 ID:???] >>770 二つ以上のプロセスが同時に追記したら、データが混じる可能性があるし。 >>772 勧告ロックはそうはいかない。 >>774 PHPは面倒みてくれるけど、mod_perlのファイルハンドルは無理。 だから、IO::File,FileHandleモジュールなどを使う。 perl.apache.org/docs/1.0/guide/porting.html#Filehandlers_and_locks_leakages
776 名前:770 mailto:sage [04/12/20 21:19:18 ID:???] >>772 ロックしなくて読んでいいのは、追記モードのときだけではないの? 上書きモードだと一旦中身が空になるわけで、そのときロックしないで 読んでしまったらだめだよね? 読み込んで、それをそのまま出力しておしまいな 2ch の read.cgi みたいなやつならそういうアプローチもいいだろうけど、読んだデータ を処理に利用する場合はだめと思う。 >>775 >>770 のやつ 「書込時にちゃんとロックする前提で」っていうのが抜けてた。スマソ
777 名前:771 [04/12/20 21:25:49 ID:sskqg6P0] >>773 回答ありがとうございます。 やっぱパフォーマンスの問題になりますか…
778 名前:nobodyさん mailto:sage [04/12/20 21:25:58 ID:???] >>776 ロックして書き込み中は読み込もうとしてもアクセスできないだろ。
779 名前:nobodyさん mailto:sage [04/12/20 22:28:54 ID:???] >>776 追記モードでも、書き込み途中の中途半端なデータを読む可能性を考えればダメでは?
780 名前:nobodyさん mailto:sage [04/12/20 23:16:39 ID:???] >>778 なこたぁない。。 >>779 そだね けちろん: 読み込みデータがハンパでもいいタイプのシステムなら ロックは無用。読み込みデータがその後のデータに関わってくるのなら ロック白
781 名前:nobodyさん mailto:sage [04/12/20 23:47:40 ID:???] >>778 ロックの掛け方による >>779 例えば固定長なら書込み途中のデータを見分けて使わない機構とかできそうな予感がするな? >>780 そのけつろんは読みの場合限定ってことで
782 名前:nobodyさん mailto:sage [04/12/21 06:25:34 ID:???] >>778 アドバイザリロックはいくらでもロックを無視できる。
783 名前: [05/02/02 14:16:34 ID:hfbAK0ph]
784 名前:nobodyさん mailto:sage [05/02/26 07:20:55 ID:???] ロック状態を保持するデーモン作る
785 名前:nobodyさん [2005/03/27(日) 21:58:07 ID:frr01O3q] それ最強
786 名前:nobodyさん [2005/03/28(月) 02:50:20 ID:QWQNdIyl] ユーザ名とロックIDを引数にしてロック状態の設定、解除、状態取得を行えるCGIサービスを誰かやって! もちろん無料で( ̄ε ̄@)」 lock.service.jp/lock.cgi&user=xxx?id=1?timeout=60 lock.service.jp/status.cgi&user=xxx?id=1 # <html><body>OK</body></html> # <html><body>NG</body></html> lock.service.jp/unlock.cgi&user=xxx?id=1 こんな奴
787 名前:nobodyさん mailto:sage [2005/03/28(月) 03:17:29 ID:???] >>786 実在のドメインを例示に使うなと何度(ry
788 名前:nobodyさん mailto:sage [2005/03/28(月) 03:50:52 ID:???] ( ̄ε ̄@)
789 名前:nobodyさん [2005/03/30(水) 16:45:20 ID:0SN1W7SJ] 二つ以上のファイルをflockしても問題ないんですか? flock(FH, 2); flock(FH2, 2);
790 名前:nobodyさん mailto:sage [2005/03/30(水) 17:17:26 ID:???] >>789 ないよ。 # デッドロックには気を付けてね。
791 名前:nobodyさん mailto:sage [2005/03/30(水) 18:55:15 ID:???] To: lock@xxxx.xx.xx Subject: Lock user=xxxx pass=xxxx timeout=60 lock-id=1 ========== Subject: Unlock ========== Subject: Status こんな感じのメールでロック状態を管理してくれるサービスきぼんw
792 名前:nobodyさん mailto:sage [2005/03/30(水) 19:01:47 ID:???] 伝書鳩 (ry
793 名前:nobodyさん mailto:sage [2005/03/31(木) 04:46:07 ID:???] >>792 それだ! To: lock@xxxx.xx.xx Subject: Lock user=xxxx pass=xxxx timeout=60 lock-id=1 ======= ↓ 登録してある住所にlock-id確認コードを郵送 ↓ 登録ページからlock-id確認コードを入力
794 名前:789 mailto:sage [2005/03/31(木) 09:19:53 ID:???] thnx>>790
795 名前:nobodyさん mailto:sage [2005/04/02(土) 05:31:48 ID:???] rename $0 $0.tmp perl $0.tmp rename $0.tmp $0
796 名前:nobodyさん [2005/04/04(月) 15:59:12 ID:UmDaQFM/] >>795 すげw
797 名前:nobodyさん mailto:age [2005/04/08(金) 17:32:31 ID:???] ごめん、>>795 のどこがすげwのか、解説してください?
798 名前:nobodyさん mailto:sage [2005/04/08(金) 19:48:39 ID:???] 自信をリネームとかできんのかな
799 名前:nobodyさん mailto:sage [2005/04/08(金) 21:23:04 ID:???] リネームに失敗しても、他のプロセスがリネームしてるヤツがあれば実行する罠
800 名前:nobodyさん mailto:sage [2005/04/08(金) 23:18:53 ID:???] 書き込みの最中に死んだりするとデータ全部消えて無くなるな。仕方ないか。
801 名前:nobodyさん mailto:sage [2005/04/09(土) 19:52:50 ID:???] >>800 ゆーあーばか
802 名前:nobodyさん [2005/06/06(月) 21:34:45 ID:nLjgLi0T] sub create_lock { for ($i = 0; $i < 10; $i++) {#10回繰り返す return if link($0, $lock);#link関数でロックファイルが作成できれば終了 sleep(1);#作れない場合は1秒スリープしてから再挑戦 } print "BUSY";#10回以内にロックできない場合はBUSYと表示 exit;#スクリプト終了 } ↑だとうまくいくのに、↓だとうまくいかないのは何ででしょうか? ↓ですとsleepを5回繰り返した後&error("BUSY")の処理をします。 sub create_lock { local($retry) = 5; # 1分以上古いロックは削除する if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; if ($mtime < time - 60) { &unlock; } } while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error("BUSY");#5回以内にロックできない場合はBUSYと表示 } sleep(1); } exit; }
803 名前:nobodyさん mailto:なかな [2005/06/06(月) 21:38:25 ID:???] あかさたなはまやらわあかさたなはまやらわあかさたなはまやらわあかさたなはまやらわあかさたなはまやりわあかさたなはまやらわあかさたなはまやらわあかさたなはまやらを
804 名前:nobodyさん [2005/06/06(月) 23:11:37 ID:pBVz6jtY] >>802 よくわからんがmkdirに成功するとwhileループを抜けてすぐ exitするからじゃないか? それ以外にも古いロックを削除するあたりが突っ込みどころ ありそうだが、サブルーチンunlockがどういうものか示されて ない以上は疑惑レベルだな。
805 名前:nobodyさん [2005/06/07(火) 11:44:43 ID:Jzx4SwvB] なぜこれでロックがかかるのでしょうか? フォルダを作って消してるだけのような気がするんですけど。 ↓ &createlock();#mkdirでロックファイルを作成する open(FILE,"+<$logfile"); 〜(処理)〜 close(FILE); &unlock;#rmdirでロックファイルを削除する
806 名前:nobodyさん mailto:sage [2005/06/07(火) 12:33:20 ID:???] createlock と unlock の中身がわからないとなんとも・・・。
807 名前:nobodyさん mailto:sage [2005/06/07(火) 15:11:06 ID:???] サーバー環境によって使えたり使えなかったりする関数の一覧みたいなのって WEBに転がってませんかね? 環境 A B C flock × ○ ○ mkdir ○ ○ ○ こんな感じの一覧表みたいなのがあればいいな
808 名前:nobodyさん mailto:sage [2005/06/07(火) 18:06:21 ID:???] >>804 802です。お答えありがとうございました。 ごめんなさい、勘違いしてました。ちゃんとロックできました。 ところで、質問ですけども、 sub create_lock { local($retry) = 5; if (-e $lockfile) { local($mtime) = (stat($lockfile))[9]; # ←この部分の[9] if ($mtime < time - 60) { &unlock; } } while (!mkdir($lockfile, 0755)) { if (--$retry <= 0) { &error("BUSY"); } sleep(1); } exit; } ↑の文章の local($mtime) = (stat($lockfile))[9]; 特に[9]の意味が分からないのですが、この文章は何を意味するのでしょうか?
809 名前:nobodyさん mailto:sage [2005/06/07(火) 19:19:30 ID:???] >>808 statはファイルの様々な情報を長いリストにして返す関数で、その9番目の 要素であるところのファイル更新時間だけ欲しいから[9]で取り出してると いうことだな。詳しくはperldoc -f statでもしてくれ。
810 名前:nobodyさん mailto:sage [2005/06/07(火) 20:02:25 ID:???] >>809 ありがとうございました。理解できました。
811 名前:nobodyさん mailto:sage [2005/06/07(火) 20:15:05 ID:???] >>809 前から疑問に思っていたんだが、 > 9番目 0から始まっているから、この場合10番目なのはみんな知っていると思うけど、9番目といってもいいのかな? どういう言い方が正しいのか教えて。
812 名前:nobodyさん mailto:sage [2005/06/07(火) 20:59:09 ID:???] 9番目の要素(ninth element)、0番目の要素(zeroth element)でいいと思うけど、 9番の要素、0番の要素の方がすっきりする?
813 名前:nobodyさん mailto:sage [2005/06/07(火) 22:14:04 ID:???] 質問です。かの有名なperlメモで以下のように書きました。 my_flockのサブルーチンの中で、戻り値を「\%lfh」のようにリファレンスで返す理由がわかりません。どなたか教えてください $lfh = my_flock() or die 'Busy!'; open(FILE,"+<$logfile"); chop($count = <FILE>); $count++; seek(FILE,0,0); print FILE "$count\n"; close(FILE); my_funlock($lfh); sub my_flock { my %lfh = (dir => './lockdir/', basename => 'lockfile', timeout => 60, trytime => 5, @_); $lfh{path} = $lfh{dir} . $lfh{basename}; for (my $i = 0; $i < $lfh{trytime}; $i++, sleep 1) { return \%lfh if (rename($lfh{path}, $lfh{current} = $lfh{path} . time)); } # ■↑戻り値がなぜ\%lfh? opendir(LOCKDIR, $lfh{dir}); my @filelist = readdir(LOCKDIR); closedir(LOCKDIR); foreach (@filelist) { if (/^$lfh{basename}(\d+)/) { return \%lfh if (time - $1 > $lfh{timeout} and rename($lfh{dir} . $_, $lfh{current} = $lfh{path} . time)); last; # ■↑戻り値がなぜ\%lfh? } } undef; } sub my_funlock { rename($_[0]->{current}, $_[0]->{path}); }
814 名前:nobodyさん mailto:sage [2005/06/07(火) 22:35:39 ID:???] my_funlockで$lfh{current}と$lfh{path}の2つの値を使いたい ので、この作者は(他にもいろいろ方法は考えられるがたまたま) その2つの値が入ったハッシュのリファレンスを返すという方法 を選択した、というところだろうか。
815 名前:nobodyさん [2005/06/08(水) 00:31:21 ID:HPDd28CP] >>813 戻り値無しで if (rename($lfh{path}, $lfh{current} = $lfh{path} . time)); return; とやっても同じ
816 名前:nobodyさん mailto:sage [2005/06/08(水) 12:02:28 ID:???] ここのカウンター広告ないし最高だよ。 www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/ www.eucaly.net/
817 名前:nobodyさん [2005/06/08(水) 12:12:58 ID:???] >>815 違うような・・・
818 名前:nobodyさん [2005/06/08(水) 13:04:42 ID:???] >>814 お答えありがとうございました。 何かの弾みで「./lockdir/lockfile」の名前が変わってしまうことってありますか? その場合ってエラーを返すしかないのでしょうか?
819 名前:nobodyさん [2005/07/02(土) 23:42:28 ID:MoVRWRYG] PHPで掲示板のログファイルを読み込んで配列に入れるのに file()を使ってたんですが、これはロックされてないですよね? fopenしてflockに変更した方がいいですか?
820 名前:nobodyさん mailto:sage [2005/07/03(日) 19:24:42 ID:???] >>819 スレタイを声を出して100回読んでみなさい。
821 名前:nobodyさん mailto:sage [2005/07/06(水) 15:38:22 ID:???] ファイルロック(排他処理)について語ろう
822 名前:nobodyさん mailto:sage [2005/07/06(水) 20:01:43 ID:???] ファイルロック(排他処理)について語ろう
823 名前:nobodyさん mailto:sage [2005/07/07(木) 11:51:39 ID:???] file関数は読み込みしかしないからロックも何もない
824 名前:nobodyさん [2005/07/11(月) 12:06:06 ID:LOhIsGf7] open LOCK, ">hogehoge"; flock LOCK, 2; 処理; ↑のようにLOCKをしっぱなしで、closeをしないとどうなりますか? 一連の処理が終了したら、LOCKは自動解除されるんでしょうか?
825 名前:nobodyさん mailto:sage [2005/07/11(月) 15:42:12 ID:???] PGが終了すればファイルハンドルは閉じられる。
826 名前:nobodyさん mailto:sage [2005/07/11(月) 16:23:12 ID:???] ファイルロック難しいお
827 名前:nobodyさん [2005/09/29(木) 15:27:47 ID:6eWvRT5D] エクセルでテンポラリがリネームに失敗するのは排他処理に失敗したこと による可能性はありますか?
828 名前:nobodyさん mailto:sage [2005/09/30(金) 17:50:44 ID:???] ロック用ファイル1に時刻書き込み ↓ ロックファイル1に時刻がなかったらロック用ファイル2を開いてロック(あったら待機) ↓ 一時ファイルに書き込み ↓ 読み込み用ファイルに内容をコピー ↓ ロック用ファイル2を閉じる ↓ ロック用ファイル1を空にする 最強、破損なし。 時刻は異常があった時に現在時刻と比較して無限待機させない用。
829 名前:nobodyさん mailto:sage [2005/09/30(金) 18:31:16 ID:???] >>828 「1に時刻書き込み」してから「1に時刻がなかったら」をチェックするのは変じゃない?
830 名前:nobodyさん mailto:sage [2005/09/30(金) 21:17:53 ID:???] それよりロック用ファイル1のロックはどうするんだ
831 名前:nobodyさん mailto:sage [2005/09/30(金) 21:28:52 ID:???] 「破損なし」なのは「ロック用ファイル2」をロックしてるからだけで、 本質的には目新しいアイディアがひとつも無いどころか 単に無駄なことしてるだけに思えるのは気のせいですかそうですか。
832 名前:nobodyさん [2005/10/09(日) 23:29:44 ID:nlo5+ZWx BE:169416465-##] >>828 はなしにならんな。 あきれたよ。もう実家に帰る!
833 名前:nobodyさん [2005/12/08(木) 21:09:42 ID:pHM0ErCM] perlを始めて3ヶ月位ですが、ファイルロックに ついて自分なりに色々と試行錯誤した結果、以下の ようなルーチンを作りました。 flockが使える事が前提ですが、何か欠点や改良点が あれば指摘して頂けるとありがたいです。 filelock.pl package filelock; our %_lock; sub END { foreach my $file ( keys %_lock ) { close( $_lock{$file}{'handle'} ); unlink( $_lock{$file}{'name'} ); if( $_lock{$file}{'tmp'} ) { rename( $_lock{$file}{'tmp'}, $file ); } } } sub readOpen { my ( $file ) = @_; my ( $handle ); _append( $file ); if( !open( $handle, "<$file" )) { return undef; } return $handle; }
834 名前:nobodyさん [2005/12/08(木) 21:10:10 ID:pHM0ErCM] sub writeOpen { my ( $file ) = @_; my ( $handle ); _append( $file ); if( !$_lock{$file}{'tmp'} ) { $_lock{$file}{'tmp'} = $file; $_lock{$file}{'tmp'} =~ s/(.*)\.(.*)/$1\.tmp/; } if( !open( $handle, ">$_lock{$file}{'tmp'}" )) { return undef; } return $handle; } sub _append { my ( $file ) = @_; if( $_lock{$file} ) { return; } $_lock{$file}{'name'} = $file; $_lock{$file}{'name'} =~ s/(.*)\.(.*)/$1\.lck/; open( $_lock{$file}{'handle'}, ">$_lock{$file}{'name'}" ); my $count = 0; while( !flock( $_lock{$file}{'handle'}, 2 )) { sleep( 1 ); if( $count++ > 10 ) { print '[error]Sarver Busy.'; exit; } } } 1;
835 名前:nobodyさん [2005/12/08(木) 21:14:40 ID:pHM0ErCM] ちなみに、使い方は下記のように使います。 require './filelock.pl'; $file = filelock::readOpen( "count.dat" ); $data = <$file>; close( $file ); $data = $data + 1; $file = filelock::writeOpen( "count.dat" ); print $file $data; close( $file );
836 名前:nobodyさん mailto:sage [2005/12/08(木) 23:57:56 ID:???] 普通にflock使えばいいのにと野暮な突っ込み。 斜め読みしただけだから適当に。 ノンブロッキングロックじゃないと、whileループ内は無駄。 test.txtとtest.datが同じファイルと見なされる。 ロックを解除してるところがない? サンプルスクリプトはロックが壊れる典型。
837 名前:nobodyさん mailto:sage [2005/12/09(金) 00:42:03 ID:???] >>836 解答ありがとうございます。 >ノンブロッキングロックじゃないと、whileループ内は無駄。 そうですね。2(LOCK_EX)ではなくて2|4(LOCK_EX|LOCK_NB) とすればokですね。 >test.txtとtest.datが同じファイルと見なされる。 まぁ、これは仕様という事で…(^^; >ロックを解除してるところがない? ENDの中のcloseで解除しているつもりなのですが closeではロックは自動的解除されないのでしょうか? >サンプルスクリプトはロックが壊れる典型。 どういう場合にロックが壊れるのでしょうか? ご掲示頂けるとありがたいです。
838 名前:nobodyさん mailto:sage [2005/12/09(金) 03:18:54 ID:???] >>837 ENDブロックは、スクリプトの処理の最後で処理されるので、 自動でアンロックさせたいのなら、返すファイルハンドルをオブジェクトにして、 DESTROYブロックを使ってアンロックさせる。 ついでにcloseも再定義。 ロックについては web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html
839 名前:833 mailto:sage [2005/12/09(金) 03:47:51 ID:???] >>838 意図的にENDブロックに書いています。オブジェクトを作ってDEST ROYブロックでアンロックする方法も考えたのですが… hoge01.pl read "data01.dat" read "data02.dat" -> hoge02.pl write"data01.dat" write"data02.dat" -> hoge03.pl write"data03.dat" end ↑こんな感じで読み書きしたい場合、ファイルアクセスする可能 性のある所全てでオブジェクトを保持していないといけないので、 意図的にグローバルに情報を置いて、スクリプトの終わりでEND ブロック内で一括に処理したのです。 ところで、"closeも再定義"って何ですか?
840 名前:nobodyさん mailto:sage [2005/12/09(金) 12:08:16 ID:???] closeの再定義と言ったのは、closeのオーバーライドすること。 closeでロックの開放をするのなら、自前のcloseを書いて、 そこで必要な操作を行ってから、CORE::closeを呼び出すという感じで。 と、考えていたのだけど、 どうも考え方が違ってたっぽいか。
841 名前:833 mailto:sage [2005/12/09(金) 15:36:13 ID:???] ちょっと、皆さんが勘違いしているっぽいので詳細を書きます。 readOpen 戻り値 : ファイルハンドル 機能 : 指定されたファイルの拡張子をlckに変えたファイルを flockして指定されたファイルをオープン。flockが10秒以上で きない場合は異常終了。 writeOpen 戻り値 : ファイルハンドル 機能 : 指定されたファイルの拡張子をlckに変えたファイルを flockして指定されたファイルの拡張子をtmpに変えたファイル をオープン。flockが10秒以上できない場合は異常終了。 END 機能 : readOpen,writeOpenでロックされたファイル(*.lck)を close。writeOpenで返したのファイル(ハンドル)を元の名前に リネーム。(*.tmp→*.元の拡張子) 引き続き、何か欠点や改良点があれば指摘して頂けるとありがたいです。
842 名前:nobodyさん mailto:sage [2005/12/09(金) 16:10:37 ID:???] >>841 致命的にやばい点: ENDの中でlockファイルをcloseした時点でflockは外れるので、 その後のunlockとtmpファイルのrenameがロックなしで行われる。 改善した方がいい点: readしかしない場合でも排他的にロックしてしまうのは嬉しくない。 ENDが実行されるまでロック状態が持続するので、ロックの保持 期間が長くなりそうだしdaemon的プログラムだとどうすんの? tmpの書き込み中に問題がでて取りやめたいときの手段がない (やろうと思えば%filelock::_lockいじる手はあるが...) リトライ回数が尽きたときにいきなりexitするのは汎用性がない。 せめてdieにしとけばevalでトラップする余地があるのだが。
843 名前:833 mailto:sage [2005/12/09(金) 17:26:00 ID:???] >unlockとtmpファイルのrenameがロックなしで行われる。 そうですね。renameは一番最初にやるとして、その後にunlink→ closeでしょうか?closeの前にunlinkってできるのでしょうか? >readしかしない場合でも排他的にロックしてしまうのは嬉しくない。 ここでは省略しましたが、 unlockFile( $filename ) 機能 : 強制的に指定されたファイルのロックを解除する。 というルーチンがあります。自分は、デフォルトは「最後まで排 他的にロック」。オプションで「指定したファイルのロックを解除」 っていう感じで考えてます。この方が間違いが無いと思うので。 >tmpの書き込み中に問題がでて取りやめたいときの手段 そうですね。これは、abortLockみたいなルーチンを作って最後の ENDブロックの中でrenameしないようにすれば良いんじゃないで しょうか? >リトライ回数が尽きたときにいきなりexitするのは汎用性がない。 if( $count++ > 10 ) { die "flock busy" } こんな感じで良いですかね? まだまだ経験が浅いので、先輩諸氏からの助言は為になります。 他にも欠点や改良点があれば指摘して頂けるとありがたいです。
844 名前:nobodyさん mailto:sage [2005/12/09(金) 21:41:26 ID:???] >>843 「ファイルを変更する(可能性がある)場合に排他ロック、読むだけで済む場合は共有ロック」 というのはひとつのセオリーだけれども、なぜそれがセオリーなのか、そもそもファイルロックとは何なのかを調べるなどして考えてみましょう。 >readしかしない場合でも排他的にロックしてしまうのは嬉しくない。 という >>842 の指摘にはまったく同意で、デメリットはいくらも思いつくけれど残念ながらメリットはひとつも思い浮かびません。 見境なしに排他ロックというのではファイルロックの魅力が半減以下です。 またファイルを利用している、いないに関わらずロックを離さないというのはお行儀が今ひとつ。各プロセスの実行時間が充分に短く、また起動頻度が比較的低ければ問題は出づらいでしょうけれど、少なくとも誰かに勧めることができるやり方じゃないですね。
845 名前:833 mailto:sage [2005/12/09(金) 22:03:55 ID:???] 色々な意見を参考に作り直してみました。 前作にあったバグ(read→write→readした時に*.tmpファイルから 読まない)も修正しています。 open パラメータ:通常のopenと一緒だけど使えるのは'>'と'<'のみ。 戻り値:ファイルハンドル 機能:指定されたファイルの拡張子をlckに変えたファイルを flockして指定されたファイルをオープン。flockが10秒以上で きない場合は異常終了。 close パラメータ:openで得られたファイルハンドルとオプション。 機能 : 指定されたファイルハンドルを閉じます。オプションで 1を指定するとロックを解除して書き込みがある場合はリネーム して反映。2を指定するとロックを解除して書き込みがある場合 は*.tmpファイルを削除(つまり書き込みをキャンセル) END 機能 : *.lckをclose&unlink。*.tmpがある場合は、元のファイ ル名にリネーム。 package filelock; our %_FileList; our %_HandleList; sub END { foreach my $filename ( keys %_FileList ) { if( $_FileList{$filename}{'temp'} ) { rename( $_FileList{$filename}{'temp'}, $filename ) } unlink( $_FileList{$filename}{'lock'} ); close( $_FileList{$filename}{'handle'} ); } }
846 名前:833 mailto:sage [2005/12/09(金) 22:05:50 ID:???] sub open { my ( $filename ) = @_; my ( $handle, $tempfile, $mode ); if( $filename =~ /^>.*/ ) { $filename =~ s/^>(.*)/$1/; $mode = 2 } elsif( $filename =~ /^<.*/ ) { $filename =~ s/^<(.*)/$1/; $mode = 1 } else { return undef; } if( $mode == 1 && !( -e $filename )) { return undef } if( !$_FileList{$filename} ) { my $lockname = $filename; $lockname =~ s/(.*)\.(.*)/$1\.lck/; open( $handle, ">$lockname" ); my $count = 0; while( !flock( $handle, ( 2 | 4 ))) { sleep( 1 ); if( $count++ > 10 ) { die "flock busy" } } $_FileList{$filename}{'lock'} = $lockname; $_FileList{$filename}{'handle'} = $handle; } $tempfile = $filename; if( $mode == 1 ) { if( $_FileList{$filename}{'temp'} ) { $tempfile = $_FileList{$filename}{'temp'} } if( !open( $handle, "<$tempfile" )) { die "file open error(read)" } } elsif( $mode == 2 ) { if( $_FileList{$filename}{'temp'} ) { $tempfile = $_FileList{$filename}{'temp'} } else { $tempfile =~ s/(.*)\.(.*)/$1\.tmp/; $_FileList{$filename}{'temp'} = $tempfile; } if( !open( $handle, ">$tempfile" )) { die "file open error(write)" }
847 名前:833 mailto:sage [2005/12/09(金) 22:07:31 ID:???] } $_HandleList{$handle} = $filename; return $handle; } sub close { my ( $handle, $option ) = @_; if( $option && ( $option == 1 || $option == 2 )) { close( $handle ); my $filename = $_HandleList{$handle}; if( $_FileList{$filename}{'temp'} && $option == 1 ) { rename( $_FileList{$filename}{'temp'}, $filename ) } elsif( $_FileList{$filename}{'temp'} && $option == 2 ) { unlink( $_FileList{$filename}{'temp'} ) } unlink( $_FileList{$filename}{'lock'} ); close( $_FileList{$filename}{'handle'} ); delete( $_FileList{$filename} ); delete( $_HandleList{$handle} ); } else { close( $handle ); delete( $_HandleList{$handle} ); } } 1; 例: require './filelock.pl'; $file = filelock::open( "<count.dat" ); $data = <$file>; filelock::close( $file ); $data = $data + 1; $file = filelock::open( ">count.dat" ); print $file $data; filelock::close( $file, 1 );
848 名前:nobodyさん mailto:sage [2005/12/11(日) 11:36:06 ID:???] わぁ。。 もっとシンプルなやり方あるのにぃ〜
849 名前:nobodyさん mailto:sage [2005/12/11(日) 15:20:09 ID:???] my ( $filename ) = @_; まで読んだ。
850 名前:nobodyさん mailto:sage [2005/12/11(日) 23:38:47 ID:???] どうせ>>848 は、「じゃあ、そのやり方を書いてみろ」 と言ったところで、その案に穴があるか、書けないか どっちかだろ?…という訳で、とりあえず >>848 じ ゃ あ 、 そ の や り 方 を 書 い て み ろ
851 名前:nobodyさん mailto:sage [2005/12/12(月) 10:42:51 ID:???] unlinkしてからcloseもだめです。 (Aが正常にロックを取得した状態から) B: open A: unlink C: open A: close B: flock(成功する) C: flock(成功する) flockを使うときはロックファイルは一度作ったら消さないのが わかりやすい。 どうしても削除したければ、その操作をするためのロックを 別にするとかややこしいことをする羽目になる。
852 名前:nobodyさん mailto:sage [2005/12/12(月) 21:10:57 ID:???] >>851 ん?Aがロックした状態なんだよね? B: open -> Aがロック中なので開けない A: unlink -> 自分がロック中なので削除できる C: open -> Aがロック中なので開けない A: close -> 自分のロックを外す B: flock(成功する) -> Bがロック C: flock(成功する) -> Bがロック中なので開けない…のでわ?
853 名前:nobodyさん mailto:sage [2005/12/12(月) 21:21:39 ID:???] >>852 flockによるロック中でもopenはできるのでBはopenできるし、 Aが削除した後はそのファイルは存在しないんだから、 Cは新たに同じ名前の別のファイルを作ってopenできる。 そしてことのきBとCがそれぞれロックファイルだと思って 開いたファイルは実は別のものになるというのが問題 なのです。
854 名前:nobodyさん mailto:sage [2005/12/12(月) 22:29:46 ID:???] >>853 削除したらロックが外れるのは初耳だ。 つちの環境だと open -> unlink -> sleep(10) -> close で、sleep(10)の間はflockできないんだが…。 >flockによるロック中でもopenはできるので >>833 (845)のソースではopenする前にflockの 確認してると思うけど、そりゃ、perlが内部で flock処理に入ったタイミングで他プロセスが openしたらできるかもしれないが、そしたら flock自体意味無しって事になるぞ?
855 名前:nobodyさん mailto:sage [2005/12/12(月) 22:33:12 ID:???] 正:うちの環境 誤:つちの環境 とりあえず>>853 は>>833 (845)のソースを実際に実行して 穴があってから発言したら? "俺予想"だけで発言しても意味無いよ。
856 名前:nobodyさん mailto:sage [2005/12/12(月) 22:39:11 ID:???] >>854 削除したらロックがはずれるのではなくて、同じ名前のロック ファイルを別に作れてしまう。sleep(10)の間にロックファイルを openしようとしたら存在しないので新しいファイルが作られてしまう から、当然flockもできるでしょ。 > openする前にflockの 確認してると思うけど flockはopenした後のファイルハンドルに対する操作 だから、openしてないのにできるわけないよ。ロックファイルの openと操作したいファイルのopenを混同してない?
857 名前:nobodyさん mailto:sage [2005/12/13(火) 00:46:00 ID:???] package filelock; や sub open や sub close 見ただけで、他のところ見る気なくすね。
858 名前:nobodyさん mailto:sage [2005/12/13(火) 01:24:36 ID:???] >>856 なるほどね。 しかし、open→flockの間にflockされる問題を回避する事なんてできるの? >>857 スレタイを百万回読んでスレの趣旨が名前なんて関係無いという事に気付け。
859 名前:nobodyさん mailto:sage [2005/12/13(火) 23:21:49 ID:???] > しかし、open→flockの間にflockされる問題を回避する事なんてできるの? げらげら sub openとか、package filelockなんか平気で使ってる奴はやっぱりレベル低いねえ。
860 名前:nobodyさん mailto:sage [2005/12/14(水) 00:31:33 ID:???] せっかくのflockが泣いてるぜ。。
861 名前:nobodyさん mailto:sage [2005/12/14(水) 05:19:12 ID:???] >>859 漏れは>>858 だけど>>833 じゃないんだけどなぁ。 なんか、このスレは文句ばっかりで意欲的に書き込んでる>>833 を 援護しただけなんだけど、文句言うだけがスレの趣旨みたいね。 スレ汚しスマソ。
862 名前:nobodyさん mailto:sage [2005/12/14(水) 07:59:40 ID:???] > しかし、open→flockの間にflockされる問題を回避する事なんてできるの? じゃなくて、その問題が起きないようにしないとロックになってないわけよ。 一番簡単なのは851で指摘してる通りロックファイルを削除しないこと。 ただの文句としか言えない書き込みがあるのも確かだが、まじめに バグを指摘してるのにひとくくりにして文句とか言われてもなぁ。
863 名前:833 mailto:sage [2005/12/14(水) 10:14:13 ID:???] >>848-862 色々とご指摘ありがとうございます。ロックファイルをunlinkす ると、close前にロックファイルがopen(作成)できてしまう問題を 回避する為にunlinkしない事にしました。 しかし、それだと*.lckが沢山できてしまうので、filelockディレ クトリを作ってその中に作る事にしました。同様に書き込み用の テンポラリファイルもその中に作るようにしたので、今までの *.lckや*.tmpファイル名が使えなかったり拡張子だけが違うファ イルが扱えない問題も無くなりました。 その代わり、各ディレクトリにfilelockという名前のディレクト リができます。以下にソースを晒します。 sub open { my ( $filename ) = @_; my ( $handle, $mode ); if( $filename =~ /^>.*/ ) { $filename =~ s/^>(.*)/$1/; $mode = 2 } elsif( $filename =~ /^<.*/ ) { $filename =~ s/^<(.*)/$1/; $mode = 1 } else { return undef; } if( $mode == 1 && !( -e $filename )) { return undef; } $filename =~ /(.*)(\\|\/)(.*)/; if(! -d "$1$2filelock") { mkdir("$1$2filelock", 0755); mkdir("$1$2filelock/tmp", 0755); } if( !$_FileList{$filename} ) { $filename =~ /(.*)(\\|\/)(.*)/; my $lockfile = $3 eq '' ? "$1$2filelock/$filename" : "$1$2filelock/$3"; if( !open( $handle, ">$lockfile" )) { die "file open error" } my $count = 0; while( !flock( $handle, ( 2 | 4 ))) {
864 名前:833 mailto:sage [2005/12/14(水) 10:14:38 ID:???] sleep( 1 ); if( $count++ > 10 ) { die "flock busy($lockfile)" } } $_FileList{$filename}{'lock'} = $lockfile; $_FileList{$filename}{'handle'} = $handle; } if( $mode == 1 ) { my $openfile = $filename; if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'}; } if( !open( $handle, "<$openfile" )) { die "file open error" } $_HandleList{$handle} = $filename; return $handle; } elsif( $mode == 2 ) { my $openfile = $filename; if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'}; } else { $filename =~ /(.*)(\\|\/)(.*)/; my $tempfile = $3 eq '' ? "$1$2filelock/tmp/$filename" : "$1$2filelock/tmp/$3"; $_FileList{$filename}{'temp'} = $tempfile; } if( !open( $handle, ">$openfile" )) { die "file open error" } $_HandleList{$handle} = $filename; return $handle; } return undef; } 引き続き、欠点や改良点があれば指摘して頂けるとありがたいです。
865 名前:nobodyさん mailto:sage [2005/12/14(水) 14:36:11 ID:???] というか、排他制御の何たるかが理解できてないのに、 いくらコード書いたって無駄だろ。 少なくとも誰も使わんと思うが。
866 名前:nobodyさん mailto:sage [2005/12/14(水) 20:09:27 ID:???] 文句しか書かない厨は、華麗にスルーでおながいすまつ。
867 名前:nobodyさん mailto:sage [2005/12/15(木) 00:56:13 ID:???] 文句にしか聞こえない馬鹿は、似非ロックをバグと一緒に作っていなさい。
868 名前:nobodyさん mailto:sage [2005/12/15(木) 06:51:32 ID:???] >>867 すげー苦しい言い訳だ。>>865 が文句に見えないなら 小学校の国語からやりなおした方が良いよマジで。 とりあえず漏れが>>865 が文句だと思う具体的な根拠は… ・どこが問題なのか具体的な事が書かれていない ・自分の中の意見を「誰も」と書くことで皆と同じだと思い込んでる ・文章が全体的に罵倒した口調。何かイヤな事でもあったの?(w >>833 最初に比べると随分マシになったと思うよ。 具体案を何も提示しないアホな煽りに構わず頑張って欲しい。
869 名前:nobodyさん mailto:sage [2005/12/15(木) 07:53:45 ID:???] >>865-367 2ちゃんねるですからねー 煽り煽られはあたりまえ 荒らしはスルーが基本ですよ
870 名前:nobodyさん mailto:sage [2005/12/15(木) 09:24:29 ID:???] なんてルーチン内でロック失敗してundef返すのとdieで処理を完結させるのが 混在してるの?
871 名前:nobodyさん mailto:sage [2005/12/15(木) 09:53:36 ID:???] もちっとプログラミングができるようになってからやろうな。 まだ君には早いよ。
872 名前:nobodyさん mailto:sage [2005/12/15(木) 10:22:47 ID:???] みんなに使って欲しい、というんではなく、Perlの勉強として やってんでしょうから、大目に見てやんなって。
873 名前:nobodyさん mailto:sage [2005/12/15(木) 11:10:51 ID:???] perlの勉強の前に排他制御の勉強しないから似非ロックが量産される。
874 名前:nobodyさん mailto:sage [2005/12/15(木) 12:01:28 ID:???] >>870 ファイルが無かったりオプションの指定が違ったりだとundefしてて、 ファイルに書き込めなかったりロックできなかったりするとdieしてる。 たぶん、見た感じだとundefは想定内(?)のエラー。dieは想定外(?) のエラーって感じじゃないのかな?
875 名前:nobodyさん mailto:sage [2005/12/15(木) 12:09:03 ID:???] 漏れは>>883 のソースで十分に排他制御できてると思うんだけど とりあえず>>865 >>873 が言う「排他制御」と>>833 のソースの 排他制御は何が違うのか具体的に書いてくれまいか?
876 名前:nobodyさん mailto:sage [2005/12/15(木) 22:24:03 ID:???] >>883 頑張れ。
877 名前:nobodyさん mailto:sage [2005/12/16(金) 01:11:58 ID:???] >>875 「これだから排他制御を理解してない香具師は…」って 言いたいだけなんだよ。そっとしといれやれ(w
878 名前:nobodyさん mailto:sage [2005/12/16(金) 01:57:10 ID:???] >>833 排他的なロックに対しては、それで良いと思う。テンポラリファイルを作って書き込み エラーにも対応してるし。しかし、それで全てOKという訳では無い。 例えばAというファイルをプロセス1〜10が同時に読み込み処理が行われて書き込み処理が 無い場合を考えてみよう。プロセス1が読み込み終わるまでプロセス2は読み込み処理を 行えない。読み込み処理だけならば排他的なロックは必要無いのに。 まぁ、それをわかっていて>>833 が何でも排他的なロックを使っているなら良いのだが…
879 名前:nobodyさん mailto:sage [2005/12/16(金) 03:04:17 ID:???] こうだろ? × 読み込み処理だけならば排他的なロックは必要無いのに。 ○ 読み込み処理だけならば排他的なロックは必要無いケースもあるのに。
880 名前:nobodyさん [2005/12/16(金) 05:43:26 ID:nqW99XKP] ソースは他のところに上げて、そのURLを書いてください。 すごく邪魔
881 名前:nobodyさん [2005/12/16(金) 05:44:47 ID:nqW99XKP] なにがなんでも「データを取得できずに空ページを表示」というのを防ぎたいんじゃないのかなぁ? って思ったり。
882 名前:nobodyさん mailto:sage [2005/12/16(金) 12:06:00 ID:???] 書き込みオープンだけを行うと、一回目と二回目で違うファイルを開かないか。
883 名前:nobodyさん mailto:sage [2005/12/17(土) 01:28:51 ID:???] >>882 開かないと思うけど…。それに追記に対応してないみたいだから 1回目も2回目も「新規ファイル作成」扱いになるんだよね?
884 名前:nobodyさん mailto:sage [2005/12/17(土) 02:42:54 ID:???] >>864 で、書き込みファイルの指定が > my $openfile = $filename; > if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'}; てなことになってる。 「書き込みを行って読み込み」を行うとすると、 まず書き込みで$filenameに書き込まれて、 読み込みで$_FileList{$filename}{'temp'}が読まれることになると思われる。
885 名前:nobodyさん mailto:sage [2006/01/08(日) 16:25:04 ID:???] test
886 名前:nobodyさん mailto:sage [2006/01/11(水) 15:20:26 ID:???] で、結局どうなったの?
887 名前:nobodyさん mailto:sage [2006/01/11(水) 18:09:12 ID:???] ______ ______ r' ,v^v^v^v^v^il / ヽ l / jニニコ iニニ!. / ジ き ぼ l i~^' fエ:エi fエエ)Fi ! ャ れ く l ヽr > V ! イ い は l l !ー―‐r l <. ア な l __,.r-‐人 `ー―' ノ_ ヽ ン / ノ ! ! ゙ー‐-- ̄--‐'"ハ ~^i \_ _ノ ヽ ! ヽ、_ _.ノ i \  ̄ ̄ ̄ ̄ ヾV / ! /.入
888 名前:nobodyさん mailto:sage [2006/01/23(月) 18:41:58 ID:???] renameでロックをしてみました。どうでしょうか? $nowsec=time; $lockname="./lock/lock_".$nowsec; $basename="./lock/lock"; while (1){ if (rename $basename,$lockname){&process()}; $n++; if ($n>=5){&error()}; sleep 1; }; opendir (LOCKDIR,lock); @filelist=readdir(LOCKDIR); closedir(LOCKDIR); foreach $filename (@filelist) { if ($filename=~/_/) { ($dest,$locktime)=split(/_/,$filename,2); unless ($locktime==$nowsec){ $timedif=$nowsec-$locktime; if ($timedif>=5){ rename $filename,$lockname; }; }; }; sub process{ &backname() } sub backname{ rename $lockname,$filename; }
889 名前:nobodyさん [2006/01/28(土) 10:06:37 ID:JFqaWvHV] ファイルロックと言うのは、 先にファイルを開いておいて、それからロックするものですか? オープン前に排他制御かけるのは無駄ですか?
890 名前:nobodyさん mailto:sage [2006/01/28(土) 12:03:17 ID:???] 有効。
891 名前:nobodyさん mailto:sage [2006/01/29(日) 01:06:29 ID:???] >>889 flockだとファイルハンドルが必要だから先にオープンしないといけない。
892 名前:889 [2006/01/29(日) 07:30:55 ID:rUKuWvJe] @dataにデータがある分だけ、ファイルF1とF2に全く同じデータを上書きしたい場合 こんな感じでいいのでしょうか? 上書きする部分だけループにしています。添削してもらえませんか? open(F1,">$file1")||die(); flock(F1,LOCK_EX); open(F2,">$file2")||die(); flock(F2,LOCK_EX); foreach(@data){ ($aaa,$bbb)=split(',',$_,2); print F1 "$aaa,$bbb\n"; print F2 "$aaa,$bbb\n"; } close(F1); close(F2);
893 名前:nobodyさん [2006/01/29(日) 08:51:40 ID:1QlgYllq] 1個ロックしときゃいいんじゃないの?
894 名前:nobodyさん mailto:sage [2006/01/29(日) 09:17:31 ID:???] >>892 書き出したファイルを読み出すことは無いの? @dataで書き込むデータは常に増えて、減ることはないの? 上二つのどちらかでも該当すると ">"でオープンするのはまずいと思われ。
895 名前:nobodyさん mailto:sage [2006/01/29(日) 10:16:26 ID:???] 定番どころをまとめておくか。 search.cpan.org/~nwclark/perl-5.8.7/pod/perlfunc.pod#flock www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq5.html#how_can_i_lock_a_file web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html homepage1.nifty.com/glass/tom_neko/web/web_04.html www.bioinfo.jp/tips.html#flock www.din.or.jp/~ohzaki/perl.htm#File_Lock
896 名前:flock [2006/01/29(日) 16:44:40 ID:rUKuWvJe] >>893 F1とF2で別々のファイルを開くのに、ロックは1つで良いのですか!? >>894 このcgiファイルでは、このF1やF2は上書きだけで終了です。 このスクリプトの中でF1およびF2の中に追加項目があったりするので、それを足したのをまた同じF1やF2に上書きするという処理をさせています。 ですので、このファイルでは >書き出したファイルを読み出すことは無いの? >@dataで書き込むデータは常に増えて、減ることはないの? ということは無いです。 ただですね、他のcgiファイルでは読込みがあります。 F1とF2では用途が違うので同じ内容を2つに分けていますが、片方はダウンロードして使いたいのでCSVファイル、もう片方が他で読み込んで使う用途にtxtファイルにしています。 このtxtファイルの方も、他のcgiファイルのスクリプトの中で読み込みはしますが、項目が減ったり増えたりすることはありません。 私は、この部分が変に冗長になっているのではないかと思い、他に良い書き方は無いかと考えてみたのですが どうしても他の方法が浮かばなかったのでこちらの専門スレに投稿させて頂いた次第です。 良かったら、他の書き方があればご教授願えませんでしょうか? >>895 ありがとうございます。 その内4つは調べている段階で既読でした。 他のサイトを拝見してきます。
897 名前:flock [2006/01/29(日) 17:31:41 ID:rUKuWvJe] >>895 今拝見してきたのですが、端的にflockの使い方良し悪しについて述べられているサイトを見つけるのが難しい中、プロセスから易しく書かれたものが見つけられました。 ありがとうございました。 その中にあった web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html#99 の「ゴミ」というところに似た書き方をしているのではと、かなり不安になりました。 特にCSVファイルの方は、サーバからダウンロードして後から情報の閲覧や整理に使いたいので (@dataに追加するデータは、ある条件を満たすもののみ○、そうでないものは何も書かないというごく簡単なものですが) ○では無いのに○が付いてしまったり、またはその逆などのエラーがあると困ってしまうのです。 ますますもって、このままで良いのか不安になってきました。 ファイルロックについて、このサイトのようにプロセスから細かく記されている書籍などはご存じないでしょうか? もし、お暇でしたら私のスクリプトの不安箇所の訂正などして頂けたらありがたいのですが....
898 名前:nobodyさん mailto:sage [2006/01/29(日) 18:07:38 ID:???] >>892 open(F1,"+<$file1")||die(); flock(F1,LOCK_EX); open(F2,"+<$file2")||die(); flock(F2,LOCK_EX); ... truncate(F2, tell(F2)); close(F2); truncate(F1, tell(F1)); close(F1); ($file1,2は既に存在するとして)こんな感じかな。 同じ内容なら、一つのファイルにすることを考えた方がいいかも。 リンク張るとか。 > 「ゴミ」というところに似た書き方をしているのではと、かなり不安になりました。 同じファイルに対して排他的なロックすることで起こるデッドロックだね。 関係があるとしたら、File2とFile1を逆順に排他的にロックするプログラムが有るとき。 そのときはデッドロックを引き起こす可能性がある。
899 名前:nobodyさん mailto:sage [2006/01/29(日) 19:15:17 ID:???] >>897 lock は結局読み込みから書き込みまでの間に何をするかなんだよな。 (読み込みが含まれるのは読み込んで書き込むまでの間に他の プロセスが書き込みを行ってしまっていた場合に、新たに書き込む データが既存のデータを壊してしまうから。) だから本当は書き込みのところだけ晒されても正しいのかどうかは 判断できない。 ロックで具体的にこうしろというコードが表に出てこないのは そういう理由もある。
900 名前:はは [2006/03/02(木) 23:54:04 ID:KQkmhtbv] 士ね
901 名前:nobodyさん [2006/03/03(金) 01:03:50 ID:QWJoZw1q] 更新処理はこうしてる。 if (!open(ORI,"$original_file")) { &error; } if (!open(TMP,"> $tmp_file")) { &error;} if (!open(LOCK, "$lock_file")){&error;} flock(LOCK, 2); while ($_ = <ORI>) { #各種更新処理 print TMP "$changed_line"; }; close(ORI); close(TMP); &lock; flock(LOCK, 8); close(LOCK); sub lock { $list = `ls $ls`; @lists = split(/\s+/,$list); @lists = grep(/\.tmp/,@lists); @lists = grep(!/$tmp_file/,@lists); if (@lists) { if (-e "$tmp_file") { unlink("$tmp_file"); } &error; } if (!rename("$tmp_file","$original_file")) { &error; } ; chmod 0666,"$original_file"; } システムが瀕死の状態ん時に(年に1度ぐらい)壊れるが。
902 名前:nobodyさん mailto:sage [2006/03/03(金) 02:34:58 ID:???] open my $lock, "> $lock_file" or die; flock $lock, LOCK_EX|LOCK_NB or die; open my $in, "< $data_file" or die; open my $out, "> $tmp_file" or die; while (my $line = <$in>) { # bra bra bra . . . . . print $out $line or die; } close $out or die; close $in; rename $tmp_file, $data_file or die; close $lock; とかでいいんじゃね?
903 名前:nobodyさん [2006/03/03(金) 20:34:19 ID:QWJoZw1q] >>902 flockを信じればそれでもいけるが、テンポファイルが何らかの障害で生き残った場合 リネームで致命傷。 ユニークなファイル名にしといた方が安全かなと。
904 名前:nobodyさん mailto:sage [2006/03/03(金) 22:52:47 ID:???] つFile::Temp
905 名前:nobodyさん mailto:sage [2006/03/04(土) 01:20:31 ID:???] flockを信じればって、じゃあ何を信じりゃいいのさ? つか、flockすんならテンポラリファイルいらねーだろ。
906 名前:nobodyさん mailto:sage [2006/03/04(土) 03:20:16 ID:???] use Fcntl qw/:DEFAULT :seek/; sysopen my $fh, $file, O_RDWR|O_CREAT|O_EXLOCK, 0600 or die $!; my $sz_file = -s $fh; sysread $fh, my($buf), $sz_file or die $!; my @data = split /\n/, $buf; : : my $sz_data = length($buf = join "\n", @data); sysseek $fh, 0, SEEK_SET or die $!; if ($sz_data < $sz_file) { $buf .= "\n" x ($sz_file - $sz_data); syswrite $fh, $buf, $sz_file or die $!; truncate $fh, $sz_data or die $!; } else { syswrite $fh, $buf, $sz_data or die $!; } close $fh;
907 名前:nobodyさん mailto:sage [2006/03/04(土) 15:29:33 ID:??? BE:79061827- ] >>905 書き出し中に再起動したらどうする? 書き出し中に電源落ちたらどうする?
908 名前:nobodyさん mailto:sage [2006/03/04(土) 20:19:13 ID:???] 排他処理とは関係ないけど、907が言うような障害対策?を まとめたサイトってありますか?
909 名前:nobodyさん mailto:sage [2006/03/04(土) 23:28:46 ID:???] >>907 そこまで考える必要があるなら、DB使うよw
910 名前:nobodyさん [2006/03/05(日) 00:08:23 ID:j4KtSVTy] >>909 そこまで考えるとDB使っても無理。 データは壊れるものと思って、定期的なバックアップは必要。 もちDBのほうが壊れにくいが、それでもMySQLなんて更新多いと壊れる事はある。 このスレはDB使えなくて、それでも極力ファイル破損させたくないって人が対象だろうから、 flock+店舗ファイルが正解なんじゃない? 共用鯖使ってる人が多いだろうけど、そういう鯖は完全に落ちなくてもflock効いてない時結構あったよ。 俺の借りてた鯖の場合は店舗ファイル使って、ずいぶん壊れにくくなったなぁと思うんだけど。 今は自鯖あるから俺もDB使っているけど。
911 名前:nobodyさん mailto:sage [2006/03/05(日) 01:35:17 ID:???] open my $lock, "> $lock_file" or die $!; flock $lock, LOCK_EX; tie @data, "DB_File", $data_file, O_RDWR|O_CREAT, 0666, $DB_RECNO or die $!; # 更新処理 untie @data; close $lock; これで壊れたことないんだけど、何か問題ある?
912 名前:nobodyさん mailto:sage [2006/03/05(日) 05:29:10 ID:???] >>902 >>911 君らの方法でFAな気が酢
913 名前:nobodyさん mailto:sage [2006/03/05(日) 10:29:48 ID:???] いやいや、 > LOCK_NB or die; って、少しは待ってみるとかalarm仕込むとかしようよ。
914 名前:nobodyさん mailto:sage [2006/03/06(月) 09:58:45 ID:???] >>910 > そこまで考えるとDB使っても無理。 SQLite3 なんかはトランザクション中に再起動や電源断があっても大丈夫って言ってるみたい。 やりかた次第じゃないかな。
915 名前:nobodyさん mailto:sage [2006/03/06(月) 20:50:40 ID:???] いや、だから、ロックファイル+テンポリネームが答えなんじゃ・・・
916 名前:nobodyさん mailto:sage [2006/03/06(月) 21:18:04 ID:???] テンポリネームwww
917 名前:nobodyさん mailto:sage [2006/07/14(金) 18:34:43 ID:???] ここでよいのか分かりませんが。。 このスレを参考にflockでかなりファイルが壊れなくなりました 頭が下がる思いです で、最近処理速度が気になります。 無論ハード面での影響があるとは思いますがflockで処理するより MySQLなどを使った方が処理速度は飛躍的に向上しますか? えろいひと教えて下さい
918 名前:nobodyさん mailto:sage [2006/08/18(金) 23:57:42 ID:???] >>917 データ構造が巨大かつ複雑で、そこから任意の情報をいやらしい感じに読み書きするような話なのであれば、RDBMS に SQL 渡して丸投げしたほうが *効率は* いいと思う。 餅は餅屋というやつだ。
919 名前:七誌 [2006/10/27(金) 22:34:40 ID:Cj9z7A7l] くぁWせDFRGTYふじKぉP;@:
920 名前:nobodyさん mailto:sage [2006/10/27(金) 22:50:51 ID:???] もちつけ LとOが入れ替わってるぞ
921 名前:nobodyさん mailto:sage [2006/10/28(土) 16:57:21 ID:???] すなおにsleepでいいじゃん。
922 名前:nobodyさん mailto:age [2006/11/04(土) 13:00:42 ID:???] 俺様が勉強してるからあげ
923 名前:nobodyさん [2006/11/11(土) 18:19:40 ID:umuRe6Kn] 結局、一番有効な排他処理は?
924 名前:nobodyさん [2006/11/28(火) 09:01:07 ID:+OyZsB34] すみませんが、お聞きしたいのですが、 ローカルの環境でカウンターのファイルロックの強度を試すのに、for文で1000回カウンターのファイルにアクセスするスクリプトを作り、 それをタブブラウザで10個開いておいて、全てのタブを再読み込みさせて10000回カウントされているのを見るのは有効な手段でしょうか? またネットワークにつながっているもう一台のパソコンからも、さらに同時に更新をかけて、20000回カウントされてるかどうか見るのは有効でしょうか?
925 名前:nobodyさん mailto:sage [2006/11/28(火) 09:11:11 ID:???] 「有効な手段」の定義が良くわからんが、タブブラウザ使っても httpの同時セッション数が既定の2とかだとまったく意味ナサス。 素直にab(apache bench)とか使っとけ。
926 名前:nobodyさん mailto:sage [2006/11/28(火) 10:46:03 ID:???] テストしてやるからソースを
927 名前:nobodyさん mailto:sage [2006/11/28(火) 11:35:28 ID:???] テストしてやるからサーバを
928 名前:nobodyさん mailto:sage [2006/11/28(火) 13:00:47 ID:???] テストしてやるからネットワーク接続を
929 名前:nobodyさん mailto:sage [2006/11/28(火) 16:34:07 ID:???] テストしてやるからパソコンを
930 名前:nobodyさん mailto:sage [2006/11/28(火) 17:08:23 ID:???] その前にとりあえずご飯を
931 名前:nobodyさん mailto:sage [2006/11/28(火) 19:23:59 ID:???] その前に妹を紹介して
932 名前:nobodyさん mailto:sage [2006/11/29(水) 00:11:52 ID:???] >>924 ロックには二種類しかない、駄目なロックと正しいロックだ。中間はない。 「ロックの強度」などと言うやつが作ったものは駄目なロックである可能性が非常に高い。
933 名前:nobodyさん mailto:sage [2006/11/29(水) 03:37:00 ID:???] 男は黙ってライブステージに立てロックを感じろ
934 名前:nobodyさん [2007/01/29(月) 15:46:57 ID:MdfhpFZP] 今夜ネットつながるのでファイルロックを研究するためこのスレ使いますね。PHPですけど。
935 名前:nobodyさん mailto:sage [2007/01/29(月) 17:47:33 ID:???] ずんずんちゃっずんずんちゃっ うぃ〜うぃるうぃ〜うぃるろっきゅ〜
936 名前:nobodyさん mailto:sage [2007/01/29(月) 18:21:17 ID:???] それ lock じゃなくて rock
937 名前:nobodyさん mailto:sage [2007/01/29(月) 18:45:24 ID:???] ファイルロックはデータファイル以外にロック用ファイルを用意したほうが楽だから そうしてるけどデータファイル自体をロックする場合って 一時ファイルに書き出してデータファイル名にリネームした瞬間ロック解除扱いになるんだよね? そうなるとロック待ちプロセスがデータファイルオープンしてファイルロック中にリネーム されたらファイルが存在しなくなってファイルハンドルが無効になってファイルロックが偽を返すのかな?
938 名前:nobodyさん mailto:sage [2007/01/29(月) 19:04:35 ID:???] とりあえずコードで説明して
939 名前:nobodyさん mailto:sage [2007/01/30(火) 10:08:22 ID:???] >>937 > 一時ファイルに書き出してデータファイル名にリネーム それ自体は何ら排他処理になっていない。書込途中のプロセス死亡と いったケースでデータファイルが壊れるのを防ぐ為の手順。 ロックファイルを使わずに排他処理したいなら、 open my $fh, '+<', '/path/to/file' or die $!; flock $fh, LOCK_EX; ... close $fh; のようになる。
940 名前:nobodyさん [2007/04/16(月) 16:21:56 ID:wXXA2dJL] このスレも残りわずかですね 1つ疑問いいですか? flockの有効範囲(?)っていうのがいまいち分からなくて。。 同一サーバ内、バーチャルドメインごと、1スクリプトごと。。。?? flockを使って、このスレにある方法を使い正しいロック方法の時だとします ここまで読んだものから推測するとサーバ内であれば別のスクリプトから呼び出しても効きますよね?(ファイルハンドルが同じなら) 逆に言えばflockを使っているファイルハンドルを別のスクリプトで使ったら解除してしまうってことですか? レン鯖みたいな共用鯖でよく使いそうなファイルハンドル(INとかOUTとか)でflockを使うと危険なんですかね?
941 名前:nobodyさん mailto:sage [2007/04/16(月) 16:38:48 ID:???] 言語に備わってるファイルロック関数は信用してはいけない
942 名前:nobodyさん mailto:sage [2007/04/16(月) 18:29:01 ID:???] >>940 Perlのflockは様々な実装があるので、ここではUnix互換OSのflock(2)が 使われた場合とすると、 ・flockはOSの機能なので、機能するのはOSの範囲内。 ・正しい書き方をすれば、別のプロセスがロックを外すことは無い。 ・別プロセスからのflockの開放は可能らしい。
943 名前:nobodyさん mailto:sage [2007/04/16(月) 18:31:45 ID:???] ファイル構造体にフラグ立ててるわけだからファイルハンドル・別スクリプト云々は考えなくていいっしょ
944 名前:nobodyさん mailto:sage [2007/04/16(月) 19:58:57 ID:???] mkdirが使えるなら絶対そっちのほうがいいよ
945 名前:nobodyさん mailto:sage [2007/04/23(月) 18:26:23 ID:???] >942 遅ればせながらォです
946 名前:nobodyさん mailto:sage [2007/04/23(月) 20:20:20 ID:???] NFSを介した向こう側のファイルを開く時はflockが効かなかったりする。
947 名前:nobodyさん mailto:sage [2007/04/26(木) 17:01:49 ID:???] >>946 (OSが管理してるので)同じサーバ内でならflockでいい。 別のサーバからのアクセスもロックしたいなら lockd動かしてfcntlでロックする。
948 名前:nobodyさん [2007/04/29(日) 20:50:11 ID:QRYQeqJ7] ファイルロックって、馬鹿ですか? mutex使えよ、アホ
949 名前:nobodyさん mailto:sage [2007/04/30(月) 00:26:57 ID:???] >>948 Windowsなんて糞なサーバ使うより1000万倍まし。
950 名前:nobodyさん mailto:sage [2007/04/30(月) 14:00:30 ID:???] >>946 そういうときは、fcntlを使うようにオプションで指示してコンパイルする。
951 名前:nobodyさん mailto:sage [2007/04/30(月) 14:26:51 ID:???] ファイルロック関数に頼ったロックに頼るべきではない。 独自に考えるべき
952 名前:nobodyさん mailto:sage [2007/04/30(月) 17:20:06 ID:???] ここはスレタイにあるとおり、「perl」でという制約の元の排他制御に 関する議論をするスレッドなんだよ。 しかもwebprog板なので、サーバーサイド限定だ。 すなわちWin限定の解は採点が低い。
953 名前:nobodyさん mailto:sage [2007/04/30(月) 18:09:45 ID:???] 次スレは言語選ばないべき。過疎ってるから
954 名前:nobodyさん mailto:sage [2007/04/30(月) 18:34:21 ID:???] PHPも仲間に入れてやってください
955 名前:nobodyさん mailto:sage [2007/04/30(月) 22:19:01 ID:???] PHPか。
956 名前:nobodyさん mailto:sage [2007/05/01(火) 08:41:54 ID:???] Perlで1個作って、それを移植するだけだろw
957 名前:nobodyさん mailto:sage [2007/05/01(火) 11:06:12 ID:???] >>956 ほとんど同じでOKなの?
958 名前:nobodyさん mailto:sage [2007/05/03(木) 07:37:55 ID:???] 5年前のスレかよw
959 名前:nobodyさん mailto:sage [2007/11/12(月) 23:00:45 ID:???] 半年前のレスかよ
960 名前:nobodyさん [2007/11/25(日) 15:43:12 ID:YhRNGWJK] ageてみるか
961 名前:nobodyさん mailto:sage [2008/03/14(金) 20:29:09 ID:???] このスレが無限ロックされてるんじゃね?w
962 名前:nobodyさん mailto:sage [2008/08/08(金) 02:57:43 ID:???] flockにロックIDとかつけてくんないかなー 部分ロックしたいときに困る
963 名前:nobodyさん [2008/08/08(金) 02:59:41 ID:V81X7ey0] ていうかファイルに対するlockじゃなくて、完全にIDのみで管理するロック機構があれば応用がきくのに そういうのって何で作られないの?何かわけがあるの?
964 名前:nobodyさん mailto:sage [2008/08/08(金) 10:06:25 ID:???] ファイルに対してlockしないでなににlockするんだい? 管理はファイルごとに行うんじゃなくてファイルハンドルごとに行うんじゃないかい? ま、ルールに則って処理しなければlockはいくらでも無視できるけど
965 名前:nobodyさん mailto:sage [2008/08/08(金) 19:52:28 ID:???] 何言ってんのさ。 mkdirとかを用いた方法だって、あくまで"処理のロック"だろ。 その処理ってのがファイルアクセスだったときにファイルロックになるだけでさ。 わざわざロック専用のファイル作ってそれにflockかける場合のこと考えると、「対象としてのファイルがなければロックできない」ってのはどうにも無駄な制限だと思うんだけど。 って書いたけどIDだけでの管理は共用鯖とかだと現実的じゃないな。
966 名前:nobodyさん mailto:sage [2008/08/08(金) 20:28:34 ID:???] System V IPCのセマフォ使えばいいんじゃない? perlなら組み込み関数あるし、CPANにもライブラリあるよ。
967 名前:nobodyさん [2009/09/07(月) 18:18:57 ID:0FwHnD5n] 質問です。 apacheのアクセスログの様にとにかく最後尾に追記するだけの場合、排他処理は必要ですか? use Fcntl; sysopen(OUT, $FileName, O_WRONLY|O_CREAT|O_APPEND); print OUT "aaa\n"; close(OUT); これだけで済めばいいな〜というのは甘い考えでしょうか?
968 名前:nobodyさん mailto:sage [2009/09/09(水) 17:11:40 ID:???] 追記は確か混じった。
969 名前:nobodyさん [2009/09/09(水) 17:27:59 ID:jdeXznBz] >>968 レスありがとうございます。 後で編集するので書き込まれる順序は特に気にしませんが 一応flock程度はやっておこうかなと思ってます。
970 名前:nobodyさん [2009/09/13(日) 16:22:21 ID:YylJyw/3] それは print を使うからでは。 一回のシステムコールで書き込まれるようにすれば? syswrite を使うか、バッファを無効にする。
971 名前:nobodyさん mailto:sage [2009/10/08(木) 14:28:23 ID:???] 書き込みすんだったら、 ロックは必須でしょう?
972 名前:nobodyさん mailto:sage [2009/10/12(月) 23:17:19 ID:???] このスレでも何度かいわれたし、 www.bioinfo.jp/tips.html#append に詳しく書いてある。 確認してみれ。
973 名前:nobodyさん mailto:sage [2009/10/19(月) 19:57:43 ID:???] システムに依存するけど、どの操作もアトミックにできれば、ロックはいらねぇって話だわな。