【Perl】ファイルロック(排他処理)について語ろう
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
02/06/23 10:18ID:eY2l+Gw10720nobodyさん
04/10/10 17:10:11ID:???open (IN, "count.dat");
flock(IN,2);
$count=<IN>;
$count++;
print IN $count;
close(IN);
これでいいじゃん
0721716
04/10/10 17:16:22ID:???0722nobodyさん
04/10/10 17:19:40ID:???open (IN, "+>count.dat");
0723716
04/10/10 17:36:23ID:???0724nobodyさん
04/10/10 17:43:35ID:???そんなのは一概には言えない。
各ファイルは読み込み・書き込み・両方のいずれなのか、
一度に連続して読み書きするのかなど。
0725nobodyさん
04/10/20 14:16:48ID:ejI/DpjA0726nobodyさん
04/10/21 19:09:46ID:wxBAgdgRmkdirとかにしといた方が無難かね?
それぞれでflock()したって排他かからない?
0727nobodyさん
04/10/21 19:24:18ID:???0728nobodyさん
04/10/21 23:27:35ID:???デマ飛ばすな。ボケッ
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.
0729nobodyさん
04/10/22 01:27:00ID:W+TTmfbFなるほど、結局perl,phpのflock()が同じシステムコールを使うかどうかって所ですかね?
linux(redhat)なんですが、普通にflock(2)使ってると思って良いのかなぁ。
0730nobodyさん
04/10/22 17:20:32ID:???0731nobodyさん
04/10/23 01:59:39ID:???php4.3.9/linux はソース確認したところ flock(2) 使ってないよ。fcntl(2)。
0732nobodyさん
04/10/23 02:53:34ID:???0733nobodyさん
04/10/23 04:34:45ID:???双方とも flock(2) が使える環境では flock が使われる.
また間違ってるかも知れないので、調べたソースを書いておく。
php-4.3.9 ./ext/standard/flock_compat.c
perl-5.8.5 ./pp_sys.c
0734nobodyさん
04/10/23 13:22:56ID:???flock(2)使える環境って前提になるが(BSD,SystemV,Linux?)、PerlでもPHPでもflock()でいけるのか。
NFS上のディスクは別として。
0735nobodyさん
04/10/25 18:24:04ID:???0736nobodyさん
04/10/25 19:07:12ID:???0737nobodyさん
04/11/06 19:49:00ID:em3fuQlS0738nobodyさん
04/11/06 19:58:00ID:???0739nobodyさん
04/11/07 05:49:26ID:???0740nobodyさん
04/11/07 23:08:21ID:???0744nobodyさん
04/11/08 13:12:26ID:BIj8xOyZ「一度捕まえたら、離さない・・・・・」
TAITOの名作シューティングRAY・FORCEができるのは
セガサターンだけ!
0745740
04/11/08 21:24:24ID:???0746nobodyさん
04/11/08 23:46:08ID:???0749nobodyさん
04/11/09 08:59:34ID:???0750nobodyさん
04/11/09 13:16:33ID:???0751nobodyさん
04/11/09 13:43:34ID:???0752nobodyさん
04/11/09 20:07:15ID:???NFSを使った事無いので、良く分からないので教えてください。
NFSを利用する時はflock関数にflock(2)ではなくfcntl(2)を利用するように
perlをビルドすると思いますが、それでもロックは壊れるのでしょうか。
fcntl(2)で壊れる場合、実際の解決手段として、どのようなものがあるのでしょうか。
0755nobodyさん
04/11/10 21:25:46ID:???それは、ロック機構が無くても信頼できるメールボックスの話だと思うのですが、
一般的なファイルアクセスにも使えるのでしょうか。
0756nobodyさん
04/11/12 07:07:11ID:djvAfFkIレイフォース >>>> 越えられない壁 >>>> レイヤーセクション
0757752
04/11/13 13:06:05ID:???・NFS Version4なら、ロック機構が組み込まれているので問題が無い(flock(2)でok?)
・NLM(Network Lock Manager)プロトコルに対応したサーバとクライアントならば、
fcntl(2)で対応可能。(ただし、一部のシステムで信頼が無いかも)
・それ以外はロックファイルを作るのが一般的
という感じらしいことが分かりました。
ありがとうございました。
0758nobodyさん
04/11/13 15:51:42ID:6imth/Ieレイストーム >>> レイフォース >>> レイクライシス
0759nobodyさん
04/11/14 12:08:06ID:???0760nobodyさん
04/11/15 01:32:31ID:???0761nobodyさん
04/11/18 09:27:07ID:upfr9/eiそれなに?
0762nobodyさん
04/11/18 10:10:24ID:3NzX+MnA懐かしい
0763nobodyさん
04/11/18 19:52:46ID:GLzLqJbZ0764nobodyさん
04/11/18 20:49:35ID:???0765nobodyさん
04/11/27 15:36:14ID:o5xdYnQz0766nobodyさん
04/11/27 15:54:59ID:???0769nobodyさん
04/12/04 19:37:01ID:???0770nobodyさん
04/12/20 07:41:20ID:???壊れてる可能性のあるところってバッティングしているときのだけでしょ?
0771nobodyさん
04/12/20 14:13:21ID:sskqg6P0現在1つのスクリプト中に複数の箇所でファイルロックを使ってます。
これらのファイルロックを全てやめて代わりに、
スクリプトの一番最初でダミーのファイルにロックをかけて
スクリプトの一番最後でロックを解除するようにして他のプロセスが
スクリプトを実行しているときはスクリプトの実行自体を順番待ちさせて
同時に複数のプロセスがファイルへの書き込みをできないように
変えようと思いますが、何か問題あるでしょうか?
1つ気になるのは、もしスクリプトの途中でexit関数等でスクリプトの実行が終了した場合は
自動的にダミーファイルのロックが解除されファイルも自動的にcloseされますか?
0773nobodyさん
04/12/20 15:30:20ID:???プロセスが死ねばロックは解除される。
先頭と末尾でロックと解除をするようにするのはいいが、
パフォーマンス低下は明らか。
0774nobodyさん
04/12/20 16:09:04ID:???スクリプトの実行が終了してもプロセスは死なないと思うけど
mod_* がスクリプト中の flock の後始末を面倒見てくれるんですよね?
0775nobodyさん
04/12/20 20:09:18ID:???二つ以上のプロセスが同時に追記したら、データが混じる可能性があるし。
>>772
勧告ロックはそうはいかない。
>>774
PHPは面倒みてくれるけど、mod_perlのファイルハンドルは無理。
だから、IO::File,FileHandleモジュールなどを使う。
http://perl.apache.org/docs/1.0/guide/porting.html#Filehandlers_and_locks_leakages
0776770
04/12/20 21:19:18ID:???ロックしなくて読んでいいのは、追記モードのときだけではないの?
上書きモードだと一旦中身が空になるわけで、そのときロックしないで
読んでしまったらだめだよね?
読み込んで、それをそのまま出力しておしまいな 2ch の read.cgi
みたいなやつならそういうアプローチもいいだろうけど、読んだデータ
を処理に利用する場合はだめと思う。
>>775
>>770 のやつ 「書込時にちゃんとロックする前提で」っていうのが抜けてた。スマソ
0777771
04/12/20 21:25:49ID:sskqg6P0回答ありがとうございます。
やっぱパフォーマンスの問題になりますか…
0780nobodyさん
04/12/20 23:16:39ID:???>>779
そだね
けちろん: 読み込みデータがハンパでもいいタイプのシステムなら
ロックは無用。読み込みデータがその後のデータに関わってくるのなら
ロック白
0781nobodyさん
04/12/20 23:47:40ID:???ロックの掛け方による
>>779
例えば固定長なら書込み途中のデータを見分けて使わない機構とかできそうな予感がするな?
>>780
そのけつろんは読みの場合限定ってことで
0783
05/02/02 14:16:34ID:hfbAK0ph0784nobodyさん
05/02/26 07:20:55ID:???0785nobodyさん
2005/03/27(日) 21:58:07ID:frr01O3q0786nobodyさん
2005/03/28(月) 02:50:20ID:QWQNdIylもちろん無料で( ̄ε ̄@)」
http://lock.service.jp/lock.cgi&user=xxx?id=1?timeout=60
http://lock.service.jp/status.cgi&user=xxx?id=1
# <html><body>OK</body></html>
# <html><body>NG</body></html>
http://lock.service.jp/unlock.cgi&user=xxx?id=1
こんな奴
0788nobodyさん
2005/03/28(月) 03:50:52ID:???0789nobodyさん
2005/03/30(水) 16:45:20ID:0SN1W7SJflock(FH, 2);
flock(FH2, 2);
0791nobodyさん
2005/03/30(水) 18:55:15ID:???Subject: Lock
user=xxxx
pass=xxxx
timeout=60
lock-id=1
==========
Subject: Unlock
==========
Subject: Status
こんな感じのメールでロック状態を管理してくれるサービスきぼんw
0792nobodyさん
2005/03/30(水) 19:01:47ID:???0793nobodyさん
2005/03/31(木) 04:46:07ID:???それだ!
To: [email protected]
Subject: Lock
user=xxxx
pass=xxxx
timeout=60
lock-id=1
=======
↓
登録してある住所にlock-id確認コードを郵送
↓
登録ページからlock-id確認コードを入力
0795nobodyさん
2005/04/02(土) 05:31:48ID:???perl $0.tmp
rename $0.tmp $0
0796nobodyさん
2005/04/04(月) 15:59:12ID:UmDaQFM/すげw
0798nobodyさん
2005/04/08(金) 19:48:39ID:???0799nobodyさん
2005/04/08(金) 21:23:04ID:???0800nobodyさん
2005/04/08(金) 23:18:53ID:???0802nobodyさん
2005/06/06(月) 21:34:45ID:nLjgLi0Tfor ($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;
}
0803nobodyさん
2005/06/06(月) 21:38:25ID:???0804nobodyさん
2005/06/06(月) 23:11:37ID:pBVz6jtYよくわからんがmkdirに成功するとwhileループを抜けてすぐ
exitするからじゃないか?
それ以外にも古いロックを削除するあたりが突っ込みどころ
ありそうだが、サブルーチンunlockがどういうものか示されて
ない以上は疑惑レベルだな。
0805nobodyさん
2005/06/07(火) 11:44:43ID:Jzx4SwvBフォルダを作って消してるだけのような気がするんですけど。
↓
&createlock();#mkdirでロックファイルを作成する
open(FILE,"+<$logfile");
〜(処理)〜
close(FILE);
&unlock;#rmdirでロックファイルを削除する
0806nobodyさん
2005/06/07(火) 12:33:20ID:???0807nobodyさん
2005/06/07(火) 15:11:06ID:???WEBに転がってませんかね?
環境 A B C
flock × ○ ○
mkdir ○ ○ ○
こんな感じの一覧表みたいなのがあればいいな
0808nobodyさん
2005/06/07(火) 18:06:21ID:???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]の意味が分からないのですが、この文章は何を意味するのでしょうか?
0809nobodyさん
2005/06/07(火) 19:19:30ID:???statはファイルの様々な情報を長いリストにして返す関数で、その9番目の
要素であるところのファイル更新時間だけ欲しいから[9]で取り出してると
いうことだな。詳しくはperldoc -f statでもしてくれ。
0811nobodyさん
2005/06/07(火) 20:15:05ID:???前から疑問に思っていたんだが、
> 9番目
0から始まっているから、この場合10番目なのはみんな知っていると思うけど、9番目といってもいいのかな?
どういう言い方が正しいのか教えて。
0812nobodyさん
2005/06/07(火) 20:59:09ID:???9番の要素、0番の要素の方がすっきりする?
0813nobodyさん
2005/06/07(火) 22:14:04ID:???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});
}
0814nobodyさん
2005/06/07(火) 22:35:39ID:???ので、この作者は(他にもいろいろ方法は考えられるがたまたま)
その2つの値が入ったハッシュのリファレンスを返すという方法
を選択した、というところだろうか。
0815nobodyさん
2005/06/08(水) 00:31:21ID:HPDd28CP戻り値無しで
if (rename($lfh{path}, $lfh{current} = $lfh{path} . time));
return;
とやっても同じ
0816nobodyさん
2005/06/08(水) 12:02:28ID:???http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
0818nobodyさん
2005/06/08(水) 13:04:42ID:???お答えありがとうございました。
何かの弾みで「./lockdir/lockfile」の名前が変わってしまうことってありますか?
その場合ってエラーを返すしかないのでしょうか?
0819nobodyさん
2005/07/02(土) 23:42:28ID:MoVRWRYGfile()を使ってたんですが、これはロックされてないですよね?
fopenしてflockに変更した方がいいですか?
■ このスレッドは過去ログ倉庫に格納されています