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
システムに依存するけど、どの操作もアトミックにできれば、ロックはいらねぇって話だわな。