その場合、オペレーティング システムによってロックが解除されることはありますか?
「ロックを取得したスクリプトがクラッシュしました」と表示され、ロックが解除されますか?
ロックをすぐに解除しますか?
これらの質問はすべてシステムに依存します。Perl 5 はファイル ロック機能を実装していません。単に、、ロック、または (OS で利用可能なものに応じて) への共通インターフェイスを提供するflock(2)
だけfcntl(2)
ですlockf(3)
。プログラムが終了したとき、segfault が発生したとき、または sigkill で強制終了されたときに何が起こるかにも違いがあるかもしれません。
Linux での簡単なテストでは、通常の終了条件でロックが解除されることが示されています。
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock
次の場合に何が起こるか見てみましょうdie
。
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.
セグメンテーション違反を取得するには、C にアクセスする必要があります。私はそれを取得するために使用Inline
しています。
$ cat segfault.pl
#!/usr/bin/perl
use strict;
use warnings;
use Inline "C";
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
crash();
__DATA__
__C__
void crash() {
int* ptr = NULL;
*ptr = 5;
}
$ perl segfault.pl
got lock
Segmentation fault
$ perl segfault.pl
got lock
Segmentation fault
最後に、プログラムが送信されると次のようになりSIGKILL
ます。
$ cat fork.pl
#!/usr/bin/perl
use strict;
use warnings;
$SIG{CHLD} = "IGNORE"; #auto-reap children
die "could not fork: $!" unless defined(my $pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
sleep(100);
exit;
}
kill 9, $pid;
die "could not fork: $!" unless defined($pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
exit;
}
$ perl fork.pl
got lock
got lock
これらの実験から、懸念しているケースごとに Linux でロックが解除されていることがわかります。
また、ロックを解除せずにどのスクリプトがクラッシュ/停止したかが明確になるように、スクリプトごとに 1 つの perl インスタンスが実行されていますか?
はい、Perl 5 にはperl
スクリプトごとに 1 つのプロセスがあります。フォークしても、子は独自のperl
プロセスを取得します。perl
スレッド化は、別個のプロセスを提供しません。
注: 親プロセスがロックを取得し、ロックする前にそれを放棄しない場合、親プロセスが終了しても、子プロセスは同じロックを保持します。