【Perl】ファイルロック(排他処理)について語ろうat PHP
【Perl】ファイルロック(排他処理)について語ろう - 暇つぶし2ch468:nobodyさん
03/08/08 01:36
>>465
use Fcntl;するならO_SHLOCKとO_EXLOCKが使えるでしょ。
Win系はシラネ。

469:nobodyさん
03/08/08 04:05
>>465
うん、使える。
O_EXLOCKを使ってsysopenで書いてあげたら
もっとスマートなlockができそう。

470:nobodyさん
03/08/09 22:15
>>465
use IO::File::fock;
my $fh = new IO::File::fock('file','>>');


471:山崎 渉
03/08/15 22:42
    (⌒V⌒)
   │ ^ ^ │<これからも僕を応援して下さいね(^^)。
  ⊂|    |つ
   (_)(_)                      山崎パン

472:nobodyさん
03/08/24 11:20
flock使えます。
追記の場合って、どうするのが一番確実で負荷がかかんないんでしょうか?
僕は、データを編集する場合と同じように、以下のようにしちゃってますが。use Fcntl qw(:flock);
#万が一リネーム失敗したときのために、ユニークなファイル名にしておく
$tmpfile = "$datafile".".$$.". time() .".csv";
#ロックファイルを作成する(★注:ロックファイルは、各CSVごとにユニークに)
open (LOCKF, ">$datafile"."_lockf") or die("cannot open:$!");
    flock (LOCKF, LOCK_EX);    #ロックファイルをflockする
    open(IN, "< $datafile") or die("cannot open:$!"); # 読みのみモードで開く
        open(TMP,"> $tmpfile"); #テンポラリファイルを作成
            while ($line = <IN>){
                $line .= <IN> while ($line =~ tr/"// % 2 and !eof(IN));
                $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
                @values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_}
                 ($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
                #必要なものだけをEUCにして、出力時にSJISにする
                foreach $value (@values){
                    &jcode::convert(\$value, "euc");
                };
                #CSV形式に変換
                $newline = join ',', map {(s/"/""/g or /[\r\n,]/) ? qq("$_") : $_} @values;
                print TMP "$newline\n" ;#テンポラリファイルに1レコード書き込み
            }
            print TMP "新しい行" . "\n";
        close TMP;
    close IN;
    unlink $datafile;
    rename ($tmpfile, $datafile) or die ("cannot rename : $!");
close LOCKF;


473:472
03/08/24 11:25 xfHM1yWk
あ、よく考えたら、既存の行をいちいち@valuesにする必要はないんだ・・・
訂正。
↓これでどうでしょか?

use Fcntl qw(:flock);
#万が一リネーム失敗したときのために、ユニークなファイル名にしておく
$tmpfile = "$datafile".".$$.". time() .".csv";
#ロックファイルを作成する(★注:ロックファイルは、各CSVごとにユニークに)
open (LOCKF, ">$datafile"."_lockf") or die("cannot open:$!");
    flock (LOCKF, LOCK_EX);    #ロックファイルをflockする
    open(IN, "< $datafile") or die("cannot open:$!"); # 読みのみモードで開く
        open(TMP,"> $tmpfile"); #テンポラリファイルを作成
            while ($line = <IN>){
                print TMP $line ;
            }
            print TMP "新しい行" . "\n";
        close TMP;
    close IN;
    unlink $datafile;
    rename ($tmpfile, $datafile) or die ("cannot rename : $!");
close LOCKF;



474:472
03/08/24 11:57 xfHM1yWk
あるいはもう1つの選択枝。
単純に、

use Fcntl qw(:flock);
open(OUT, "+< $datafile");
    flock (LOCKF, LOCK_EX);
        truncate(OUT, 0);          # ファイルサイズを0バイトにする
        seek(OUT, 0, 0);            # ファイルポインタを先頭にセット
        print OUT "新しい行" . "\n";;  # 書き込む
close(OUT);                     # closeすれば自動でロック解除

・・・・どっちがいいのでしょうか・・・?

475:nobodyさん
03/08/24 12:53
>>474
追記なら

use Fcntl qw(:flock);
open(OUT, ">>$datafile");
    flock (OUT, LOCK_EX);
        seek(OUT, 0, 2);           # ファイルポインタを最後尾にセット(念のため)
        print OUT "新しい行" . "\n";;  # 書き込む
close(OUT);                     # closeすれば自動でロック解除

--
# 私はこんな感じ(Win不可)
use FileHnadle;
my $fh = new FileHandle($datafile, O_WRONLY|O_CREAT|O_APPEND|O_EXLOCK) or die;
print $fh '新しい行', "\n";
close($fh);

IO::Fileでもいいんだけど、趣味でFileHandle使ってます。

476:nobodyさん
03/08/27 11:26
某K氏のアクセス解析でFlock使うようにしようとしたのですが

open(LOG, ">$logfile") or &error("Open Error : $logfile");
flock(LOG, 2);
seek(LOG, 0, 2);
my(@lines) = <LOG>;

(if($agent =~ /MSIE 3/i) { $agent = 'MSIE 3'; }のような置換とか)

while($max-1 < @lines) { pop(@lines); }
unshift(@lines, "$agent<>$os<>$host<>$referer<>$hour<>$doc_uri<>\n");
unshift(@lines, "$addr\n");

print LOG @lines;
close(LOG);

こうすると書き込み時にログが一旦全部消えてしまい、
取得した最後のログ一行(先頭行に最終アクセスIPがあるので正確には二行)のみになってしまいます。
何処が悪いのでしょうか…

因みに元スクリプトではログを配列に読み込んだ時点で一旦閉じ、
処理後もう一度開いて書き込みという風になってたのですが、
これだと処理中に書き込まれたら駄目そうな気がしたので上のように書き換えたのです。


477:nobodyさん
03/08/27 19:09
>>476
lockどうこうより、while がおかしいのでは?
$max-1 < @lines がどういう比較かわからんけど、自分で
pop(@lines);して削除しちゃってるじゃないの
常にwhileが真で全行削除になってその後unshiftで2行追加してるだけでは?

478:nobodyさん
03/08/27 21:08
>open(LOG, ">$logfile") or &error("Open Error : $logfile");
'>'でオープンすると?
・ファイルの中身を切り詰める。
・書き込み専用でオープンする(ファイルが無ければ作成)。

>seek(LOG, 0, 2);
この意味は?
・フィル最後尾にファイルハンドルを移動する。

さすがに読めません。

479:nobodyさん
03/08/27 21:09
open(LOG, "+<$logfile") or &error("Open Error : $logfile");
flock(LOG, 2);
my (@lines) = <LOG>;

(ロックスレなので、、略)

seek(LOG, 0, 0);
truncate(LOG, 0);
print LOG @lines;
close(LOG);

上の書き方では、seekとtruncateの間で終了させられると、
ファイルの中身が失う危険性があるから、

seek(LOG, 0, 0);
print LOG @lines;
truncate(LOG, ftell(LOG));
close(LOG);

と書くといいらしいです。(実際はどうなんでしょ?)

URLリンク(www.kt.rim.or.jp)
URLリンク(www.kt.rim.or.jp)
クックブック 7.11
URLリンク(homepage1.nifty.com)

480:479
03/08/27 22:53
>truncate(LOG, ftell(LOG));
間違いでした。以下の通り。
truncate(LOG, tell(LOG));

481:nobodyさん
03/08/28 11:06
ログだったら、追記で開いて、flockしてファイルの尻seekするだけじゃ
だめなの?

482:nobodyさん
03/08/31 01:47 3rubdTEF
あるサイトでみたんだけど、
use DB_File;
use Fcntl;
open DAT,"lockfile";
flock(DAT,LOCK_EX);
tie(%hash,'DB_File',"dbfile",O_RDWR|O_CREAT,0666
---DBM代入処理
としてロックしてました。
lockfileというファイルへの排他ロックを取得しているのは
わかるんだけど、それがどうしてDBMのdbfileへのロックと
なるのかわからん。

483:nobodyさん
03/08/31 04:22
>>482
「dbfileを使うプロセスは、かならずdbfileにアクセスする前にlockfileをロックする」
という紳士協定があればうまく行く。

dbfileにアクセスするのが>>482のスクリプトだけの場合も然り。

それでもなぜか分からないなら良く考えてみ。

484:nobodyさん
03/08/31 20:24
>>482
ブロッキングを理解すると分かると思います。

flockでロックされると、LOCK_NBを指定していない限り、
排他される側はflock関数の場所で処理を止められます。

485:482
03/08/31 22:31 3rubdTEF
tieする前に必ずファイルロック処理する。
flockをLOCK_SHでした場合は%hashへの代入はしない。
上を全てのdbfileを使う処理でする。
この順番を守ればflockの段階でブロックしてtieへ進まない。
やっと、すっきりした。
>>483.484さんありがとー

486:nobodyさん
03/08/31 23:56
ついでですが、ファイルを排他ロック(LOCK_EX)するときは、
書き込みできる状態でファイルをオープンしないとロックしない
OSがあるそうです。ご注意あれ。

参考:
同じ(ような)処理をするモジュール。
URLリンク(search.cpan.org)

487:482
03/09/01 01:40
>>486
open LOCK,'<lockfile';
ってするてことですね。気をつけます。
このモジュール結構便利ですね。
ありがとございます。
perlの面白みにはまっっていく・・土日外にでてねえ・・

488:nobodyさん
03/09/01 19:13
LOCK_SHしといて、STORE~SYNCまでの間LOCK_EXにして
SYNCがかかったらSHにもどしちゃダメ?
LOCK_EXの時間は短い方がいいとおもうんだけど

489:nobodyさん
03/09/01 22:19
>>488
魅力的ですが、共有ロック(LOCK_SH)をしているところに
排他ロック(LOCK_EX)をしようとすると、
ブロックされて待たされることになります。

書き込む事がほとんどないのであれば、
検討する価値はあるかも。

ロックしたら、操作、すぐ開放が基本です。

490:488
03/09/02 11:52
> 魅力的ですが、共有ロック(LOCK_SH)をしているところに
> 排他ロック(LOCK_EX)をしようとすると、
> ブロックされて待たされることになります。
同じプロセスならLOCK_SHからLOCK_EXへ移行できちゃったんですが...


491:nobodyさん
03/09/02 20:13
言いたかったのは、こんなイメージです。

 processA     processB
   |         |
flock(F, LOCK_SH);   |
   |         |
  処理    flock(F, LOCK_EX);
   |          :
   |          :  (ブロックされる)
   |          :
 close(F);       処理 (ここで処理開始)
   |         |
   exit;        |
            close(F);
              |
             exit;

492:490
03/09/04 22:14
そっか、タイミングがちょっと遅くなるだけで、結局待たされるんだ。。。
って事でURLリンク(www.perldoc.jp)をみると・・・
まともにロックしたかったらBerkeleyDBを使えっと(´Д`;)



493:nobodyさん
03/09/06 01:39 A9Khhwgn
flockでここまでスレが伸びるのか・・・。
漏れなら小規模の場合は消えるの覚悟で単純にflockだけ(面倒)。
中規模以上はDB立ててDBのLOCKで対処。

これじゃいかんのか?

494:nobodyさん
03/09/06 02:09
俺もDBマンセー

495:nobodyさん
03/09/06 03:10
>>493
flockで消えちゃうのは、何かお前のやり方に問題があるんだと思うぞ。
システム自体がflockの堅牢性に頼っていると言うのに。

496:nobodyさん
03/09/07 02:25
flockにも限界があるので、できるなら餅は餅屋に任せるのがいいと思いますよ。

497:nobodyさん
03/09/07 10:06
>>496
限界って?
Windowsやover networkでうまく働かない以外に何か問題あったっけ?

だいたいflock使えねーとか言ってるヤツのコードみると書き方間違ってる
だけだったりするんだよな。

ごちゃごちゃ言う前にモジュール使えってのはまぁ同意だけど。

498:nobodyさん
03/09/07 14:44 AN0xO5Ef
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

ありますよ。ご自分でお調べください。

499:nobodyさん
03/09/07 15:01
>>498
あとは昔のOSでバッファをフラッシュしないくらいしか思いつかないなあ。

UN*X系のOSで別に正しく使えばファイルが消えちゃうとかはないでしょ?

500:nobodyさん
03/09/07 15:03
UNIX系でflockに対応してないものもある、見たいなのを読んだ事があるけど本当ですかね?

501:nobodyさん
03/09/07 15:04
>>499
>>496=498は適当に言ってるだけですよ。

502:nobodyさん
03/09/07 15:14
そんな感じだな

503:496
03/09/07 19:04
>>497
flockでデータベースを丸ごとロックするより、
他の方法を使ったほうが限界性能が上がると言いたかったのですが…。

別の話として。
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?
ActivePerlの場合、WIN32APIのLockFileEXが使えれば、Windowsでも使えます。
そして、それはうまく働きます。

私はflock(2)の信頼性を否定しません。
とはいえ、perlのflockについてはperldocに例外事項が書かれています。
(498さんの言いたかったのはこれかな)

perlのflock関数 = flock(2)であるとは限りません。

参考:
perldoc -f flcok
perlソース pp_sync.c
ActivePerlソース win32.c

504:nobodyさん
03/09/07 22:04
>>503
おいおい、何はぐらかしてんだ?
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
他の方法とは?

505:nobodyさん
03/09/07 22:26 K46D6zau
flockからunlockまでの途中で強引に処理を止めて、同じcgiを複数
起動させればflockの信頼性が判るよ。いくつかはロックかからずに
スルーされるからさ。

後はロックの残骸による次プロセス(同一ロック)の停止かな。
遠回りしないと解決出来ないのは面倒。

漏れが間違っているかもしれんが、同時に数千~数万単位でロックを
必要とする環境に置いて上記の理由からflockは使いたくないです。
よってほとんどDBのロックに任せっきり。DBだと単純なa=a+1の場合だと
DB自体が保証してるんでロック不必要だし。

間違っていたら本当にスマソ。業務でロックを故意に壊しにいった結果
こうなったので。

506:nobodyさん
03/09/07 22:35
>>505
ソースとdfの結果みせてみな。

そういうケースの殆どはファイルシステムがNFSだった、って
オチな訳だが。

もし本当にflock(2)に信頼性がないなら、sendmailがmailboxファイルを消しまくる
現象が世界中で起きてるはずだが。

> 後はロックの残骸による次プロセス(同一ロック)の停止かな。

・・・は?

> 間違っていたら本当にスマソ。

多分間違ってると思う。

507:nobodyさん
03/09/07 23:19
>>505
>いくつかはロックかからずにスルーされるからさ。
どうやって判断してんだ。テストコードがバグってんだろ。よくあることだ。

>ロックの残骸
って何?

>flockは使いたくないです。
>よってほとんどDBのロックに任せっきり
・・・

508:nobodyさん
03/09/07 23:54
最近は、凧や独楽を買ったものの、子供がうまく使いこなせずに「不良品じゃないのか!」と
店に怒鳴り込む馬鹿親がいると聞きますが・・・。

この業界にも、道具を使いこなす努力をせずに、自分の無能を全部道具のせいにする
DQNが増えてきたってことですかね。

509:nobodyさん
03/09/08 10:14
>508
ハゲドウ

しかし、不良だらけの道具を平気で売ってる大企業とかも在るのが実情ではある。
M$とか。

510:496
03/09/08 13:21
>おいおい、何はぐらかしてんだ?
>>Windowsやover networkでうまく働かない以外に何か問題あったっけ?

perldoc -f flockから引用
>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).

>On systems that support a real flock(), locks are inherited
>across fork() calls, whereas those that must resort to the more
>capricious fcntl() function lose the locks, making it harder to
>write servers.

というように、いい加減なfnctl(2)によりエミュレーションされた場合は
サーバーの書き込みが激しい場合ロックが失われると書いてあります。

>>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
>他の方法とは?

データベース側に専用のロック機構があれば、そちらにお任せしますが?
全部flockしますか?

511:nobodyさん
03/09/08 23:47
>>510=>>496
こいつ何言ってんだ?勝手にデータベース使うな。

512:nobodyさん
03/09/09 02:09
>>510
んじゃ、perlにflock(2)の呼び出しが実装されてれば問題がないということでよろしい
でしょうか?

俺は思わず「fcntlがダメダメ -> POSIX準拠と呼べない -> UNIX系とも呼べない」
と思ってしまったが。

513:496
03/09/09 20:09
>>512
flock(2)が機能して、正しく使えていれば問題ないかと。
私の知る限りでは、fcntl(2)でも十分信頼性はあると思いますけどね。

514:nobodyさん
03/09/12 14:11 e1VX9Ox6
flock(2)とPerlのflockを混同するから話がややこしくなるんだよな。

flock(2)はover networkじゃなく、正しく使えば基本的に堅牢。
Perlのflockはコンパイルされた環境依存、ってとこか。
fcntlでもちゃんとPOSIXに準拠してれば問題ないはず。

その腐ったfcntlを実装してるOSが何なのか知りたい。
Larryの事だから、誰も使わないようなかなりマイナーな物を
想定しているような気がするが。

しかしfcntlは堅牢でないからDBを使う、といってる人がいたが、
じゃぁそのDBはどうやってファイルをロックしてるんだろう?

515:nobodyさん
03/09/12 19:43
システムのロック以上の能力を持つロックは不可能です。

と言い切ってみるテスト…。

516:nobodyさん
03/09/13 00:45
fcntl がクソな実装を具体的に挙げられない限り、flock 否定派の香具師は議論にならん。

517:nobodyさん
03/09/13 23:39
>>516
UNIX系ならまず大丈夫、ということで良いだろ。
fcntl失敗する時点でUNIX失格だからな。

518:nobodyさん
03/09/14 21:13
>>514
PostgreSQLだったらセマフォ。

>>517
URLリンク(qmail.jp)でも触れられているが、
NFSでlockdが腐る現象がまれに発生する事を実際に経験している。
(俺は信者じゃない)

519:518
03/09/14 21:24
> PostgreSQLだったらセマフォ。
これ、やっぱ嘘かも。
しかし、排他制御のプリミティブはfcntlやflockだけではない。

520:nobodyさん
03/09/15 06:39
突然だけどflockってなんて読んでる?

521:nobodyさん
03/09/15 06:42
えふろっく

522:nobodyさん
03/09/15 07:54
ファイナルロック>510


523:nobodyさん
03/09/15 10:38
限界でもファイルロックだろうね。

524:nobodyさん
03/09/15 17:19
search.cpan.orgで、flockとかfile lockをキーで引いてみると
結構でてくるのですが、どれかお勧めはありますか?
それとも毎回自分で処理を書いたほうがいいのでしょうか?


525:nobodyさん
03/09/15 18:11
このスレでそんな質問しても無駄。
「flock は腐ってる。 DB 使え」という答えしか返ってこない。

526:nobodyさん
03/09/15 23:20
>>524
それぞれ用途が違うから、必要に応じて使えばいい。

527:nobodyさん
03/09/15 23:44
>>525
そんなこと書いてるのは約一名だろ。

>>524
perl -MConfig -e 'print $Config{d_flock}."\n"'

これ実行して「define」と出ればflock(2)が実装されてるからまず大丈夫。
ネットワーク越しでなければラクダ本に書いてあるflockのサンプルで充分。

528:nobodyさん
03/09/16 00:04
ラクダ本の見て必要無いのにseek(FH, 0, 2)とかやってる奴
何人か見た事あるので充分なのかどうかは微妙とか言ってみるテスツ。


529:nobodyさん
03/09/16 01:04
最近はseek(FH, 0, 2)いらんよね

530:nobodyさん
03/09/16 02:04
>>528
別にseekやってもオーバーヘッド以外の害はないんだし、害がある場合もレアケースながら
存在するので、的確かどうかはともかく、少なくとも「充分」ではあるのでは?

531:nobodyさん
03/09/27 12:58
こんなロック処理はどうだ?

mkdirで新規ディレクトリを作ったうえで、ロック成立条件を満たした場合にロック完了とする。
ディレクトリ名にタイムアウト時刻と共有/排他ロックの種別を埋め込む。

共有ロック時はディレクトリ作成後に、親ディレクトリのファイルリストを取得して、
自分の作ったディレクトリよりも前に排他ロックディレクトリが作成されていなければ、ロック完了。
排他ロック時も同様に、自分の作ったディレクトリよりも前にディレクトリが作成されていなければ、ロック完了。
もちろん、ファイルリスト取得時にタイムアウト時刻を過ぎたディレクトリは消去する。

環境依存せずに、read-write lock patternをperlで実装するとこうなるね。

532:nobodyさん
03/09/29 13:16
環境依存せずに。。。という話なんだけど、
flockサポートしてない環境ってそんなに一杯あるんですか?
windows 9xでサーバ立てる香具師はほっといたとして、、、
nkfのlock機構って精度低いんですか?


533:nobodyさん
03/09/30 04:58
>>532
nkf の lock 機構ってのは聞いたことないんだが、

・・・っていうか、一体いつまでおんなじような議論を堂々巡りで続ける気なんですか?!?!

534:nobodyさん
03/09/30 05:00
あ、ところで、 >>531 の方法は、
なかなか良さげっていうか、問題無さそうな気がするんですがどうなんでしょうね?

535:532
03/09/30 11:52
nfsの間違えでした(スマソ

536:nobodyさん
03/09/30 12:29
>>534
ほぼ同じ仕様のコードが既に公開されてて、有難く使わせて頂いてます。

537:531
03/09/30 17:11
>>536
どこで公開されてたか教えれ!

538:nobodyさん
03/10/02 03:29
>>536
もしかして、ここかしら?
URLリンク(www.mindcompass.sfcgi.com)

539:531
03/10/02 09:02
>>538
やっぱうちのサイトですか(w

で、今改良版を作ってるのですが、タイムアウト時刻をディレクトリ名にすると、同時にタイムアウト時刻が
違うロックを作ると誤動作するな。

だから、現在時刻をディレクトリ名にして、ディレクトリの作成時刻をタイムアウト時刻に変更すると言う
アクロバティックな操作が必要かもね。

改良版出来上がったら公開しますか?(y/n)



540:nobodyさん
03/10/02 16:33
>>539

自作CGIを評価するスレ
スレリンク(php板:470番)

何これ。恥ずかしがりやさんなのかな。


541:nobodyさん
03/10/02 22:14
>>540
さんくす。こんなスレがあるとは知りませんですた。
さっそくそっちのほうにageてみました。

542:nobodyさん
03/10/03 18:38
>>541
いやいや何か勘違いしてない?
ファイルロックの話なんだからこのスレでいいだろう。

俺の言いたかったのは>>539の最後に(y/n)があって、
何故かスレリンク(php板:470番)
yと答えてたので報告したまでです。


543:nobodyさん
03/10/03 18:51
>>531
これって安全そうでよさげな気はするんだけど、
ちょっと思ったんだけど、ものすごくアクセス多い場合に、
ディレクトリ作成~ファイルリスト検査のタイムラグのせいで、
いつまでたってもだれもロックを取得できない、ってな状況になりそうな気がする。

544:531
03/10/05 10:57
新バージョンageてみました。
今度の奴は、ロックする側のプロセスがタイムアウト時間を個別に設定できます。

URLリンク(do.sakura.ne.jp)

>>543
確かにファイルリスト検査に時間がかかるが、ならばどうしろと?


545:nobodyさん
03/10/06 12:54
>>544
いや、どうすればいいか私にも思い付きません。すいません。
単にデメリットを挙げてみただけで、
だからといってその方法が使えねーとかいう気も毛頭ありません。

546:531
03/10/06 22:56
>>544>>545
さらに一念発起してrename方式に変更してロック処理にかかる負荷を低減してみました。

rename方式でテストしたらロックがぶっ壊れるなー、とか思ってたら
ロック検証用のルーチンの書き方に問題があった罠。
同じファイルを読み込みと書き込みで2回オープンして、しかもバッファ処理をカットしてなかったので、
スクリプト上では書き込んだつもりでもファイルシステム上では「まだ」書き込まれてない場合があることに
ようやく気がついた。

教訓。
ロック処理が正しくても、ファイル入出力の部分の書き方によっては思わぬファイル破損がありうる。

547:531
03/10/07 18:17
>>546
やっぱりread-write lockってむづかしいでつね。
rename方式だと、共有ロックをかけているプロセス数が分からないといつロック解除していいかわからない。
ロックプロセス数を安全に記録するために、内部で排他ロックをかけなければいけない罠w
これでどのくらいロック処理で負荷がかかるか、だな。


548:nobodyさん
03/10/29 05:07
複数ファイルにまとめてロックを掛けるにはどうすれば良いのですか?

例えば掲示板で最初のページだけ静的なファイルにしたいという場合、
ログとその最初のページの両方を同時にロックしないといけないので。

FLOCKのディレクトリ版とかあれば便利なのですが…。


549:nobodyさん
03/10/29 06:01
>>548
ロック開始と解除の間で必要なファイルを扱えばいいだけ

ロックの仕組みを根本的に理解していないんじゃないか?
もうちょっと勉強せい

550:nobodyさん
03/10/29 08:13
【Perl】ファイルロック(排泄処理)について語ろう
スレリンク(php板)

551:nobodyさん
03/11/03 16:44
>548
URLリンク(www98.sakura.ne.jp)


552:nobodyさん
03/11/05 02:38
>551
flockってロックしたファイルが閉じるまでに開いた他のファイルまで
全部ロックしちゃうの?


553:nobodyさん
03/11/05 04:25
>>552
お前、リンク先のサイトの内容ちゃんと読んだか?

554:nobodyさん
03/11/05 11:35
>>551
リンク先面白かった。初心者にもわかりやすい情報をWebで公開してくれる人って、尊敬。

555:nobodyさん
03/11/05 14:16
>>553
読んだけど。
かいつまんで書くと

lockfileを開く
lockfileをロック
count.txtを開く
上書き
count.txtを閉じる
addr.txtを開く
追記
addr.txtを閉じる
lockfileをアンロック

だよね。
count.txtとaddr.txtには直接ロックかけてなくて
lockfileをロックすることによりこの二つのファイルもロックされてるらしいから
>551みたいに言った。


556:nobodyさん
03/11/05 14:16
552だ。

557:nobodyさん
03/11/05 14:28
ああ何となく解ってきた。
よく考えたらlockfileがロックされてるときはそこから先に進まないから大丈夫なのか。


558:nobodyさん
03/11/08 02:04
ロック用ファイル作らなくても
どっちかのファイルにロックかけて最後まで開いてるままで十分だけどな。


559:nobodyさん
03/11/08 13:26
>>558
あんた無茶苦茶言いますなぁ・・・

560:nobodyさん
03/11/08 13:37
無茶苦茶???いったい何が???

561:nobodyさん
03/11/08 15:28
>>559
count.txtにロックかけてそのままabbr.txtの処理終わるまで開いときゃ良いじゃん。


562:nobodyさん
03/11/08 17:35
addrだった。

563:nobodyさん
03/11/09 03:10
>>561
レアケースだろうけど
似たような事して壊れたことあるよ
無茶苦茶って事では無いだろうが、
そのやり方だと同時オープンで
2人アクセスしてきたのに1しかカウントアップしないって
ケースがタイミング良ければ発生する程度かな

564:nobodyさん
03/11/09 10:32
>>561
どうやってロックするんですか?

565:nobodyさん
03/11/09 14:47
>>563
なんでそうなる?単にヘボ実装だっただけじゃないの?

566:nobodyさん
03/11/09 15:19
>>563
なるわけないだろうが

567:nobodyさん
03/11/09 18:12
>563
単に読み込みをブロックしてなかっただけってオチなんじゃ。
それか二つのファイルでファイルハンドルを同じにしちゃったとか…。

>564
open(COUNT, "+<$cfile");
flock(COUNT, 2);
(中略)
open(ADDR, ">>$afile");
(中略)
close(ADDR);
couse(COUNT);


568:nobodyさん
03/11/09 18:18
ちょっと複雑なシステムで
複数のスクリプトが複数の同じファイルを読み書きする場合は
ロック用ファイルを一つ用意する方が管理が楽なのは当たり前。

でもカウンターのようにファイルが単一のスクリプトからしか読み書きされない場合は
どちらか先に読む方のファイルをロックしておけば十分。


569:nobodyさん
03/11/09 18:46
>>565
>>566
無能か?(w
ググルとたくさんでてくるぞ、そのケース

570:nobodyさん
03/11/09 18:58
わけわかんね。
サーバがflockをきちんと使えないシステムを採用してたとかじゃないの?


571:nobodyさん
03/11/09 19:03
>>569
きっと君と同じぐらい無能なやつなんだろうね
ここでそんなこと言ってるのも君ぐらいだし

572:nobodyさん
03/11/09 19:42 BVCYv2fe
>>570,571
馴れ合いはよそでやれよ・・・
ま、>>555は書いてるとうりにすれば問題無し
わざわざ混乱させんでもよかろうに

573:572
03/11/09 19:48
ageちまっていいスレだよな・・・

それか、
>>567-571はジエン厨じゃあなかろうなぁ?


574:nobodyさん
03/11/09 19:55 4SnYD/Cs
 | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
 |.本日選挙は20時迄!|
 |__________|
   ∧∧ ||
   ( ゚д゚)|| <残り10分切ったど!
   / づ     投票してない香具師は自衛隊の代わりにイラク逝けよ。

※総務省によると、総選挙の中間投票状況は
9日午後4時現在、全国平均で40.04%。前回を1.40ポイント下回っている。

575:nobodyさん
03/11/09 19:59
>>573
あれが自演ならお前さんも>>569か?って事になるじゃん…。
本当だったら煽った挙句自演呼ばわりですかって感じで笑えるけど。


576:nobodyさん
03/11/09 20:28
>>569
ハァ?
じゃあ「そのケース」とやらをここに貼れよ。
そのヘボ実装を検証してみようや。

577:nobodyさん
03/11/09 20:54
>>572
馴れ合い?

578:nobodyさん
03/11/09 21:14
>>577
「馴れ合い」の意味を知らないだけだろ。無知は構うな。ほっとけ。

579:564
03/11/10 14:47
あれ?flockが使える環境の人もこのスレの需要あったの?
まぁどっちでもこの場合変わらないけど。

580:nobodyさん
03/11/10 14:53
>>561が勝手にflockと勘違いして
勝手に自分のやり方を押しつけたって事かぁ(・∀・)

581:nobodyさん
03/11/10 16:11
>>580
ということにしたいのですね? :-)

582:nobodyさん
03/11/10 16:19
もうほっとけほっとけ

583:nobodyさん
03/11/10 16:43
♪か~な~しみ~に~であうた~び~

584:nobodyさん
03/11/10 16:56
↓【Perl】flock() の使えない環境下でのファイルロック(排他処理)について語ろう

585:nobodyさん
03/11/10 20:26
俺ん中の結論はRename形で、不雑なものになると管理が難しくなるんだよなぁ

586:nobodyさん
03/11/10 20:34
>>585
何の管理?

587:nobodyさん
03/11/10 20:37
同じディレクトリに複数のDATがある場合
ユニークなファイル名を生成するようにしないと。

…今思ったけど、たいした事無いなw

588:蟻の子一匹通さないロック
03/11/14 04:40 uv5dJ3X6
10 GOTO アルカトラズ島;  # ロックへようこそ
20 処理;             
30 逆転無罪;          # 真犯人逮捕⇒釈放

589:nobodyさん
03/11/14 05:44
>>580
>551からの流れでずっとflockの話だったわけだが。


590:nobodyさん
03/11/14 16:05
どっちでも変わらん。
つーか変わってくるとしたらあれだ・・・


掲示板とかのスクリプトで
LOG→HTML随時吐き出し型
じゃなく
LOG=HTMLを表示する型
の場合、Rename型の排他処理は行えない可能性がある。

ということで。
結論から言えば退避ファイル名をhtml→htmとか適当に変えればいいんだろうけど。

591:nobodyさん
03/11/14 17:52
このスレって二つの話題が流れてるんだが。

・flockが使えない環境ではどうしてる?
・ロックの有効性はその方法でなく、ロックを組み込む場所が大事。壊れる原因の大半は誤った使い方によるものなので、ありがちな落とし穴の再検証をしよう。

後者をよく理解してない初心者・中級者が、「flockで壊れた!flock使えねー」とわめいて、前者と後者をまぜこぜにして語って、スレが荒れるのが常。


592:nobodyさん
03/11/14 18:00
それでわめいてるやつは中級とは言えないだろう

593:nobodyさん
03/11/14 18:11
1 nobodyさん 02/06/23 10:18 ID:eY2l+Gw1
 どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません

594:nobodyさん
03/11/14 18:32
>>593
そいつは日本語が初心者なんだよw

595:nobodyさん
03/11/14 18:38
たった今594が1を煽りました。

596:nobodyさん
03/11/14 18:55
さあ、>>1よ щ(゚Д゚щ)カモーン!!

597:nobodyさん
03/11/15 08:26
>>590はどうなの?

598:nobodyさん
03/11/16 17:30
横レスすまんが、MySQLでも突っ込んでおけば、lockはぜんぶDBが
やってくれるやん・・・・・・・・ってのはだめなの?
あくまでOSにLockさせないとあかん?

599:nobodyさん
03/11/16 17:34
はいはい、あっち行ってね

600:nobodyさん
03/11/16 21:35
>>598
どうしてそうやって意地でも議論をループさせようとしますか?

601:nobodyさん
03/11/17 02:04
あーごめん。実用の話じゃなくて、神学論争だったのね。
空気よめなかった。すまそ。

602:nobodyさん
03/11/17 02:16
>>601
ていうか DB 使えるならその方がいいし、既に過去レスで全く同じやりとりが何度も出てるし。

603:nobodyさん
03/11/18 14:37
>>601
釣れますか?

604:nobodyさん
03/11/18 17:29
たとえば解析なしのアクセスカウンターにSQL使ってるのを俺は見た事ないな
俺が見た事ないだけかもしれないが

605:nobodyさん
03/11/18 22:15
>>604 大規模サイトだと解析前提だからDBだな。そのほうが楽だし。
個人サイトならカウンタCGIを置くだけでしょ。壊れても問題ないし。

どしてもというなら、セマフォ管理するプロセスを立ち上げといて
それ使うって手もあるのかもしれんがそれならDB使うよ。
OSのファイルロックはアトミックじゃないっす。ソラリスでもそう。
マルチアクセス前提のファイルシステムもあるが、民生用じゃないな。

606:nobodyさん
03/11/21 00:36
>>605
大規模サイトが、アクセスカウンターで解析するか?
ふつー、Webサーバのアクセスログを解析するだろ。

> OSのファイルロックはアトミックじゃないっす。ソラリスでもそう。
お前の使い方がヘボなだけ。

607:nobodyさん
03/11/21 01:22
>>606 ログ解析だけで済めば世の中楽だよなー

608:nobodyさん
03/11/21 01:56
607だけだとあおりみたいだから、いちおー。
確かに大規模サイトにはカウンタはないな。でもユーザーごとにレスポンスを
細かく制御すると、リアルタイムなユーザー管理いるからどうしてもDB。
ログ解析だけだとマーケティングデータしか出てこない。インタラクティブ
リアルタイムにそれ使わないと意味なしな。
静的なサイトでページビューだけでいいならログだけでいいけど、それじゃ
このスレの話題ずれる。
ちなみに俺はDB使わない程度のサイトならservletでロック処理。

609:nobodyさん
03/11/21 02:13
>>608
スレタイを何度も声を出してよく読んでから発言した方が良いのでは?
どう考えてもあなたのレスはどれもこのスレにはお呼びでないと思うのですが?

610:nobodyさん
03/11/21 02:23
>>609 あーすまん。607はあんまり口だすつもりなかったんだが
このスレには、人のことを「ヘボ」としか言わないやつがいて
それがどうもしゃくに障ったんでな。Perlの話しなくてスマソ。

611:nobodyさん
03/11/22 00:21
>>608
Webアプリなら自前でログ持つ、バグ対応すること考えれば当たり前。

「ソラリス」なんて呼ぶ奴が「OSのファイルロックはアトミックじゃないっす」といった時は
使い方間違ってる確率99.9999%

612:nobodyさん
03/11/23 05:00
「そらりす」って読んでた(;´Д`)アヒャ

613:nobodyさん
03/11/23 05:24
>>612
いや、その読み方で合ってるし。

614:nobodyさん
03/11/23 05:41
ところでDBMSで使ってるロック機構ってのは具体的にどんな処理なんでしょうか
単純に思いつくのはキューですが・・・
やっぱデーモンみたいな別プロセスに一括一元管理させるのが安全っちゃ安全ですよね?

615:nobodyさん
03/12/04 07:40
ここは進行遅いですね。

結局、実用に耐えるファイルロックはどれなのか
スクリプト例でまとめて欲しい。おねがいエロイヒト。

616:nobodyさん
03/12/04 11:19
>>10,>>12

617:nobodyさん
03/12/13 19:02
昨日新しいファイルロック法思いついたんだけど寝て起きたら忘れてた

618:nobodyさん
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)のソースを実際に実行して
穴があってから発言したら?
"俺予想"だけで発言しても意味無いよ。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch