1 名前:nobodyさん [02/06/23 10:18 ID:eY2l+Gw1] どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
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:???] システムに依存するけど、どの操作もアトミックにできれば、ロックはいらねぇって話だわな。