極悪です。
Zazel さんの [TSperl:316] Re: flockの使い方? から
>>> 自分の環境で flock が使えるかどうか確かめるため、下のような
>>> スクリプトを書いて試してみました:
>>
>> SolarisのC言語ライブラリにはflock()がありませんから
>> fcntl()ベースで動くはずなので、それなら予想された動きです。
>>
>> # 同じプロセス上で複数回のwrite lockは素通りするはず。
>
>Cだとflock()でも同じプロセス上ではブロックされないので、
>ロックを試す場合は別プロセスが確実だと思います。(forkだけもダメ)
なるほど。書き直して試したら納得のいく結果が得られました。
--^flock1.pl
#!/usr/local/bin/perl
++$|;
print qq(Content-type: text/html; charset=EUC-JP\r\n\r\n);
sub LOCK_SH{ 1 }
sub LOCK_EX{ 2 }
sub LOCK_UN{ 4 }
sub LOCK_NB{ 8 }
#my $lockmode = LOCK_EX|LOCK_NB;
my $lockmode = LOCK_EX;
my $file = "flocktest.txt";
do{ sleep 1 }until(time =~ m/9$/);
do{ 123 }until(time =~ m/0$/);
# 0 : ファイルをロック
open(FILE1,">$file");
flock(FILE1,$lockmode);
select FILE1; $| = 1;
print FILE1 time," : $$ : flock ok\n";
# 4 : ロック解除
sleep 4;
print FILE1 $@;
print FILE1 time," : $$ : unlock ok\n";
close FILE1;
select STDOUT;
print qq(<HTML><BODY><H1>$$</H1><PRE>),`cat $file`,q(</PRE></BODY></HTML>);
--$
--^flock2.pl
#!/usr/local/bin/perl
#use strict;
++$|;
print qq(Content-type: text/html; charset=EUC-JP\r\n\r\n);
sub LOCK_SH{ 1 }
sub LOCK_EX{ 2 }
sub LOCK_UN{ 4 }
sub LOCK_NB{ 8 }
#my $lockmode = LOCK_EX|LOCK_NB;
my $lockmode = LOCK_EX;
my $file = "flocktest.txt";
my $log;
do{ sleep 1 }until(time =~ m/9$/);
do{ 123 }until(time =~ m/0$/);
# 1 : ロックを試みる(たぶん失敗)
sleep 1;
eval{
local $SIG{ALRM} = sub{ die time," : $$ : flock 1 time-out!\n"};
alarm 1;
open(FILE2,">>$file");
flock(FILE2,$lockmode) or die time," : $$ : flock 1 failure!\n";
select FILE2; $| = 1;
print FILE2 time," : $$ : flock 1 ok?\n";
close FILE2;
alarm 0;
};
$log .= $@;
alarm 0;
# 2 : ロック失敗でアラームで抜けた場合
# 4 : アラームが効かずロックに成功するまで待った場合
# 5/7 : ロックを試みる(たぶん成功)
sleep 3;
eval{
local $SIG{ALRM} = sub{ die time," : $$ : flock 2 time-out!\n"};
alarm 1;
open(FILE2,">>$file");
flock(FILE2,$lockmode) or die time," : $$ : flock 2 failure!\n";
select FILE2; $| = 1;
print FILE2 time," : $$ : flock 2 ok?\n";
close FILE2;
alarm 0;
};
$log .= $@;
alarm 0;
# 失敗したときのメッセージ
open(FILE2,">>$file");
select FILE2;
print FILE2 $log;
close FILE2;
select STDOUT;
print qq(<HTML><BODY><H1>$$</H1><PRE>),`cat $file`,q(</PRE></BODY></HTML>);
--$
flock1.pl と flock2.pl をよーいドンで動かして、でき上がった
flocktest.txt というファイルの中身を確認します。
alarm がない Windows 2000 では、flock2(536) は
flock1(2092) がロックを解除するのを待つので
--^flocktest.txt
1076601430 : 2092 : flock ok
1076601434 : 2092 : unlock ok
1076601434 : 536 : flock 1 ok?
1076601437 : 536 : flock 2 ok?
--$
sun4-solaris(@nifty)では、alarm が効いて flock1(17946) の
ロック解除を待たずに flock2(23711) の処理が進むので
--^
1076601370 : 17946 : flock ok
1076601374 : 17946 : unlock ok
1076601375 : 23711 : flock 2 ok?
1076601372 : 23711 : flock 1 time-out!
--$
という結果になりました。flock はちゃんと効いていることがわか
りました。ありがとうございました。
--
極悪, FZH01112 at nifty.com
http://hpcgi1.nifty.com/dune/gwiki.pl?