この場合、オペレーティングシステムによってロックが解放されていますか?
「ねえ、ロックを取得したスクリプトがクラッシュしました」と表示され、ロックが解除されますか?
すぐにロックを解除しますか?
これらの質問はすべてシステムによって異なります。 Perl 5はファイルロック機能を実装していないので、flock(2)
、fcntl(2)
ロック、またはlockf(3)
(OSで使用可能なものによって異なる)への共通インタフェースを提供するだけです。また、プログラムが終了したとき、セグメンテーションが失敗したとき、またはsigkillで殺されたときにどうなるかの違いがあるかもしれません。
$ 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
ときに何が起こるか見てみましょう:
Linuxでの簡単なテストは、ロックは通常の終了条件下で除去されていることを示して
$ 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には、スクリプトごとに1つのperl
プロセスがあります。あなたがフォークしても、子供はそれ自身のperl
プロセスを取得します。スレッディングは別のプロセスを提供しません。perl
注:親プロセスがロックを取得してロックする前にロックを放棄しない場合、親が終了しても子プロセスは同じロックを持ちます。
すばらしい解答、ありがとう!また、短くてもsoulSurfer2010に感謝しますが、まだ正解です。 –