2011-07-20 22 views
2

私が次のことをすると、ロックファイルが表示されません(flock()がそれを使用している場合)?私のファイルロックで何が問題になっていますか?

問題は、同じスクリプトを複数回実行でき、ファイルをファイルしないということです。

Fnctlパッケージをインストールする必要がありますか?

私は間違っていますか?

#!/usr/bin/perl 

use warnings; 
use strict; 
use Fcntl ':flock'; # Import LOCK_* constants 

my $file = 't'; 
my $can_lockin = 1; 

open(my $fh, '>', $file) or die "Could not open '$file' - $!"; 
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!"; 

print $fh $can_lockin; 
sleep 100000000; 

#close($fh) or die "Could not write '$file' - $!"; 

答えて

2

私はあなたがこのような何かをしたいと思う:

#!/usr/bin/perl 
use strict; 
use Fcntl ':flock'; 

$|++; # no buffering 

my $file = "status.txt"; 

open my $fh, '+<', $file or die "can't open $file in update mode: $!\n"; 
flock($fh, LOCK_EX) or die "couldn't get lock: $!\n"; 
my $status = <$fh>; 
chomp $status; 
$status = $status ? '0' : '1'; 
seek $fh, 0, 0; 
print $fh "$status\n"; 
truncate($fh, tell($fh)); 

#print "blocking...\n"; sleep 10; 

close $fh; 

これは私がアップデート」でファイルを開いてることを1と0の ノートの間で前後にstatus.txtファイルの内容を切り替えます私は読んで、書く必要があるので、 "モード"を選択してください。 このようにしないと競合状態に陥ることがあります。 「スリープ」行のコメントを外すと、 が1つのウィンドウで起動され、もう1度別のウィンドウで実行されると、 が表示され、最初の実行がファイルを閉じるまで2番目の実行が待機しますロック)。

+0

恐ろしい!それは非常に良いユースケースです。あなたは私がそれを何のために使うのか推測できますか? =) –

+1

'$ | ++;'はあなたが使っていないSTDOUTにのみ影響します。 – ikegami

+1

右 - 私はそれをよりよく説明していたはずです。 $ | ++は群れのものとは関係ありません。しかし、この例では、「ブロッキング」を印刷してから10秒待ってもらいたいと思っていました。その間に2番目のウィンドウでもう一度実行すると、最初の実行が終了してロックが解除されるまで、2番目の「ブロック中」が表示されません。しかし、バッファリングがオンの場合、最初の実行が終了するまで、最初の "ブロック"メッセージは表示されません。 – scorpio17

4

flockロックファイルは使用しません。オペレーティングシステムによって実装されています。

UNIXロックは、勧告です。つまり、flockを呼び出さない限り、他のプログラムはファイルを変更できます。また、ファイルがロックされている場合、flockはブロックを試みます(ファイルがロックされるまで待機します)。保持されているロックを取得しようとしたときにブロックの代わりにプログラムを終了させたい場合は、LOCK_EX | LOCK_NBflockに渡します。

はまた、あなたのオープンモードは、(ファイルを切り捨てる)、あなたはおそらく(読み取りと書き込みのためにファイルを開く)と、あなたがロックを取得した後に自分自身をtruncateを呼び出す<+をしたいの代わりに>で、間違っていることに注意してください。

1

あなたには、いくつかのデバッグ出力を追加する場合は、(その群れを見ることができます)をブロックして、あなたのスクリプトは、ほぼ右取り組んでいる:

... 
print "Pre lock\n"; 
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!"; 
print "Post lock\n"; 
... 

あなたはLOCK_NBとビットごとの論理和LOCK_EXであることを修正することができます。

関連する問題