【Perl】ファイルロック(排他処理)について語ろう
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001nobodyさん
02/06/23 10:18ID:eY2l+Gw10892889
2006/01/29(日) 07:30:55ID:rUKuWvJeこんな感じでいいのでしょうか?
上書きする部分だけループにしています。添削してもらえませんか?
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);
0893nobodyさん
2006/01/29(日) 08:51:40ID:1QlgYllq0894nobodyさん
2006/01/29(日) 09:17:31ID:???書き出したファイルを読み出すことは無いの?
@dataで書き込むデータは常に増えて、減ることはないの?
上二つのどちらかでも該当すると ">"でオープンするのはまずいと思われ。
0895nobodyさん
2006/01/29(日) 10:16:26ID:???http://search.cpan.org/~nwclark/perl-5.8.7/pod/perlfunc.pod#flock
http://www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq5.html#how_can_i_lock_a_file
http://web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html
http://homepage1.nifty.com/glass/tom_neko/web/web_04.html
http://www.bioinfo.jp/tips.html#flock
http://www.din.or.jp/~ohzaki/perl.htm#File_Lock
0896flock
2006/01/29(日) 16:44:40ID:rUKuWvJeF1とF2で別々のファイルを開くのに、ロックは1つで良いのですか!?
>>894
このcgiファイルでは、このF1やF2は上書きだけで終了です。
このスクリプトの中でF1およびF2の中に追加項目があったりするので、それを足したのをまた同じF1やF2に上書きするという処理をさせています。
ですので、このファイルでは
>書き出したファイルを読み出すことは無いの?
>@dataで書き込むデータは常に増えて、減ることはないの?
ということは無いです。
ただですね、他のcgiファイルでは読込みがあります。
F1とF2では用途が違うので同じ内容を2つに分けていますが、片方はダウンロードして使いたいのでCSVファイル、もう片方が他で読み込んで使う用途にtxtファイルにしています。
このtxtファイルの方も、他のcgiファイルのスクリプトの中で読み込みはしますが、項目が減ったり増えたりすることはありません。
私は、この部分が変に冗長になっているのではないかと思い、他に良い書き方は無いかと考えてみたのですが
どうしても他の方法が浮かばなかったのでこちらの専門スレに投稿させて頂いた次第です。
良かったら、他の書き方があればご教授願えませんでしょうか?
>>895
ありがとうございます。
その内4つは調べている段階で既読でした。
他のサイトを拝見してきます。
0897flock
2006/01/29(日) 17:31:41ID:rUKuWvJe今拝見してきたのですが、端的にflockの使い方良し悪しについて述べられているサイトを見つけるのが難しい中、プロセスから易しく書かれたものが見つけられました。
ありがとうございました。
その中にあった
http://web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html#99
の「ゴミ」というところに似た書き方をしているのではと、かなり不安になりました。
特にCSVファイルの方は、サーバからダウンロードして後から情報の閲覧や整理に使いたいので
(@dataに追加するデータは、ある条件を満たすもののみ○、そうでないものは何も書かないというごく簡単なものですが)
○では無いのに○が付いてしまったり、またはその逆などのエラーがあると困ってしまうのです。
ますますもって、このままで良いのか不安になってきました。
ファイルロックについて、このサイトのようにプロセスから細かく記されている書籍などはご存じないでしょうか?
もし、お暇でしたら私のスクリプトの不安箇所の訂正などして頂けたらありがたいのですが....
0898nobodyさん
2006/01/29(日) 18:07:38ID:???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を逆順に排他的にロックするプログラムが有るとき。
そのときはデッドロックを引き起こす可能性がある。
0899nobodyさん
2006/01/29(日) 19:15:17ID:???lock は結局読み込みから書き込みまでの間に何をするかなんだよな。
(読み込みが含まれるのは読み込んで書き込むまでの間に他の
プロセスが書き込みを行ってしまっていた場合に、新たに書き込む
データが既存のデータを壊してしまうから。)
だから本当は書き込みのところだけ晒されても正しいのかどうかは
判断できない。
ロックで具体的にこうしろというコードが表に出てこないのは
そういう理由もある。
0900はは
2006/03/02(木) 23:54:04ID:KQkmhtbv0901nobodyさん
2006/03/03(金) 01:03:50ID:QWJoZw1qif (!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度ぐらい)壊れるが。
0902nobodyさん
2006/03/03(金) 02:34:58ID:???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;
とかでいいんじゃね?
0903nobodyさん
2006/03/03(金) 20:34:19ID:QWJoZw1qflockを信じればそれでもいけるが、テンポファイルが何らかの障害で生き残った場合
リネームで致命傷。
ユニークなファイル名にしといた方が安全かなと。
0904nobodyさん
2006/03/03(金) 22:52:47ID:???0905nobodyさん
2006/03/04(土) 01:20:31ID:???つか、flockすんならテンポラリファイルいらねーだろ。
0906nobodyさん
2006/03/04(土) 03:20:16ID:???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;
0908nobodyさん
2006/03/04(土) 20:19:13ID:???まとめたサイトってありますか?
0910nobodyさん
2006/03/05(日) 00:08:23ID:j4KtSVTyそこまで考えるとDB使っても無理。
データは壊れるものと思って、定期的なバックアップは必要。
もちDBのほうが壊れにくいが、それでもMySQLなんて更新多いと壊れる事はある。
このスレはDB使えなくて、それでも極力ファイル破損させたくないって人が対象だろうから、
flock+店舗ファイルが正解なんじゃない?
共用鯖使ってる人が多いだろうけど、そういう鯖は完全に落ちなくてもflock効いてない時結構あったよ。
俺の借りてた鯖の場合は店舗ファイル使って、ずいぶん壊れにくくなったなぁと思うんだけど。
今は自鯖あるから俺もDB使っているけど。
0911nobodyさん
2006/03/05(日) 01:35:17ID:???flock $lock, LOCK_EX;
tie @data, "DB_File", $data_file, O_RDWR|O_CREAT, 0666, $DB_RECNO or die $!;
# 更新処理
untie @data;
close $lock;
これで壊れたことないんだけど、何か問題ある?
0913nobodyさん
2006/03/05(日) 10:29:48ID:???> LOCK_NB or die;
って、少しは待ってみるとかalarm仕込むとかしようよ。
0914nobodyさん
2006/03/06(月) 09:58:45ID:???> そこまで考えるとDB使っても無理。
SQLite3 なんかはトランザクション中に再起動や電源断があっても大丈夫って言ってるみたい。
やりかた次第じゃないかな。
0915nobodyさん
2006/03/06(月) 20:50:40ID:???0916nobodyさん
2006/03/06(月) 21:18:04ID:???0917nobodyさん
2006/07/14(金) 18:34:43ID:???このスレを参考にflockでかなりファイルが壊れなくなりました
頭が下がる思いです
で、最近処理速度が気になります。
無論ハード面での影響があるとは思いますがflockで処理するより
MySQLなどを使った方が処理速度は飛躍的に向上しますか?
えろいひと教えて下さい
0918nobodyさん
2006/08/18(金) 23:57:42ID:???データ構造が巨大かつ複雑で、そこから任意の情報をいやらしい感じに読み書きするような話なのであれば、RDBMS に SQL 渡して丸投げしたほうが *効率は* いいと思う。
餅は餅屋というやつだ。
0919七誌
2006/10/27(金) 22:34:40ID:Cj9z7A7l0920nobodyさん
2006/10/27(金) 22:50:51ID:???0921nobodyさん
2006/10/28(土) 16:57:21ID:???0922nobodyさん
2006/11/04(土) 13:00:42ID:???0923nobodyさん
2006/11/11(土) 18:19:40ID:umuRe6Kn0924nobodyさん
2006/11/28(火) 09:01:07ID:+OyZsB34ローカルの環境でカウンターのファイルロックの強度を試すのに、for文で1000回カウンターのファイルにアクセスするスクリプトを作り、
それをタブブラウザで10個開いておいて、全てのタブを再読み込みさせて10000回カウントされているのを見るのは有効な手段でしょうか?
またネットワークにつながっているもう一台のパソコンからも、さらに同時に更新をかけて、20000回カウントされてるかどうか見るのは有効でしょうか?
0925nobodyさん
2006/11/28(火) 09:11:11ID:???httpの同時セッション数が既定の2とかだとまったく意味ナサス。
素直にab(apache bench)とか使っとけ。
0926nobodyさん
2006/11/28(火) 10:46:03ID:???0927nobodyさん
2006/11/28(火) 11:35:28ID:???0928nobodyさん
2006/11/28(火) 13:00:47ID:???0929nobodyさん
2006/11/28(火) 16:34:07ID:???0930nobodyさん
2006/11/28(火) 17:08:23ID:???0931nobodyさん
2006/11/28(火) 19:23:59ID:???0932nobodyさん
2006/11/29(水) 00:11:52ID:???ロックには二種類しかない、駄目なロックと正しいロックだ。中間はない。
「ロックの強度」などと言うやつが作ったものは駄目なロックである可能性が非常に高い。
0933nobodyさん
2006/11/29(水) 03:37:00ID:???0934nobodyさん
2007/01/29(月) 15:46:57ID:MdfhpFZP0935nobodyさん
2007/01/29(月) 17:47:33ID:???うぃ〜うぃるうぃ〜うぃるろっきゅ〜
0936nobodyさん
2007/01/29(月) 18:21:17ID:???0937nobodyさん
2007/01/29(月) 18:45:24ID:???そうしてるけどデータファイル自体をロックする場合って
一時ファイルに書き出してデータファイル名にリネームした瞬間ロック解除扱いになるんだよね?
そうなるとロック待ちプロセスがデータファイルオープンしてファイルロック中にリネーム
されたらファイルが存在しなくなってファイルハンドルが無効になってファイルロックが偽を返すのかな?
0938nobodyさん
2007/01/29(月) 19:04:35ID:???0939nobodyさん
2007/01/30(火) 10:08:22ID:???> 一時ファイルに書き出してデータファイル名にリネーム
それ自体は何ら排他処理になっていない。書込途中のプロセス死亡と
いったケースでデータファイルが壊れるのを防ぐ為の手順。
ロックファイルを使わずに排他処理したいなら、
open my $fh, '+<', '/path/to/file' or die $!;
flock $fh, LOCK_EX;
...
close $fh;
のようになる。
0940nobodyさん
2007/04/16(月) 16:21:56ID:wXXA2dJL1つ疑問いいですか?
flockの有効範囲(?)っていうのがいまいち分からなくて。。
同一サーバ内、バーチャルドメインごと、1スクリプトごと。。。??
flockを使って、このスレにある方法を使い正しいロック方法の時だとします
ここまで読んだものから推測するとサーバ内であれば別のスクリプトから呼び出しても効きますよね?(ファイルハンドルが同じなら)
逆に言えばflockを使っているファイルハンドルを別のスクリプトで使ったら解除してしまうってことですか?
レン鯖みたいな共用鯖でよく使いそうなファイルハンドル(INとかOUTとか)でflockを使うと危険なんですかね?
0941nobodyさん
2007/04/16(月) 16:38:48ID:???0942nobodyさん
2007/04/16(月) 18:29:01ID:???Perlのflockは様々な実装があるので、ここではUnix互換OSのflock(2)が
使われた場合とすると、
・flockはOSの機能なので、機能するのはOSの範囲内。
・正しい書き方をすれば、別のプロセスがロックを外すことは無い。
・別プロセスからのflockの開放は可能らしい。
0943nobodyさん
2007/04/16(月) 18:31:45ID:???0944nobodyさん
2007/04/16(月) 19:58:57ID:???0945nobodyさん
2007/04/23(月) 18:26:23ID:???遅ればせながら�です
0946nobodyさん
2007/04/23(月) 20:20:20ID:???0947nobodyさん
2007/04/26(木) 17:01:49ID:???(OSが管理してるので)同じサーバ内でならflockでいい。
別のサーバからのアクセスもロックしたいなら
lockd動かしてfcntlでロックする。
0948nobodyさん
2007/04/29(日) 20:50:11ID:QRYQeqJ7mutex使えよ、アホ
0951nobodyさん
2007/04/30(月) 14:26:51ID:???独自に考えるべき
0952nobodyさん
2007/04/30(月) 17:20:06ID:???関する議論をするスレッドなんだよ。
しかもwebprog板なので、サーバーサイド限定だ。
すなわちWin限定の解は採点が低い。
0953nobodyさん
2007/04/30(月) 18:09:45ID:???0954nobodyさん
2007/04/30(月) 18:34:21ID:???0955nobodyさん
2007/04/30(月) 22:19:01ID:???0956nobodyさん
2007/05/01(火) 08:41:54ID:???0958nobodyさん
2007/05/03(木) 07:37:55ID:???0959nobodyさん
2007/11/12(月) 23:00:45ID:???0960nobodyさん
2007/11/25(日) 15:43:12ID:YhRNGWJK0961nobodyさん
2008/03/14(金) 20:29:09ID:???0962nobodyさん
2008/08/08(金) 02:57:43ID:???部分ロックしたいときに困る
0963nobodyさん
2008/08/08(金) 02:59:41ID:V81X7ey0そういうのって何で作られないの?何かわけがあるの?
0964nobodyさん
2008/08/08(金) 10:06:25ID:???管理はファイルごとに行うんじゃなくてファイルハンドルごとに行うんじゃないかい?
ま、ルールに則って処理しなければlockはいくらでも無視できるけど
0965nobodyさん
2008/08/08(金) 19:52:28ID:???mkdirとかを用いた方法だって、あくまで"処理のロック"だろ。
その処理ってのがファイルアクセスだったときにファイルロックになるだけでさ。
わざわざロック専用のファイル作ってそれにflockかける場合のこと考えると、「対象としてのファイルがなければロックできない」ってのはどうにも無駄な制限だと思うんだけど。
って書いたけどIDだけでの管理は共用鯖とかだと現実的じゃないな。
0966nobodyさん
2008/08/08(金) 20:28:34ID:???perlなら組み込み関数あるし、CPANにもライブラリあるよ。
0967nobodyさん
2009/09/07(月) 18:18:57ID:0FwHnD5napacheのアクセスログの様にとにかく最後尾に追記するだけの場合、排他処理は必要ですか?
use Fcntl;
sysopen(OUT, $FileName, O_WRONLY|O_CREAT|O_APPEND);
print OUT "aaa\n";
close(OUT);
これだけで済めばいいな〜というのは甘い考えでしょうか?
0968nobodyさん
2009/09/09(水) 17:11:40ID:???0969nobodyさん
2009/09/09(水) 17:27:59ID:jdeXznBzレスありがとうございます。
後で編集するので書き込まれる順序は特に気にしませんが
一応flock程度はやっておこうかなと思ってます。
0970nobodyさん
2009/09/13(日) 16:22:21ID:YylJyw/3一回のシステムコールで書き込まれるようにすれば?
syswrite を使うか、バッファを無効にする。
0971nobodyさん
2009/10/08(木) 14:28:23ID:???ロックは必須でしょう?
0972nobodyさん
2009/10/12(月) 23:17:19ID:???http://www.bioinfo.jp/tips.html#append に詳しく書いてある。
確認してみれ。
0973nobodyさん
2009/10/19(月) 19:57:43ID:???0974nobodyさん
2010/12/07(火) 00:32:09ID:???0975nobodyさん
2010/12/07(火) 00:36:21ID:???0976nobodyさん
2010/12/07(火) 00:42:44ID:???0977nobodyさん
2010/12/07(火) 00:48:12ID:???0978nobodyさん
2010/12/07(火) 00:52:46ID:???0979nobodyさん
2010/12/07(火) 01:02:14ID:???0980nobodyさん
2010/12/07(火) 01:08:46ID:???0981nobodyさん
2010/12/07(火) 01:14:46ID:???レス数が950を超えています。1000を超えると書き込みができなくなります。