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