2012-09-29 11 views
8

(ここでは擬似コードで)次のPerlコードを想像してみて:Perlスクリプトは、その場合、2行目で終わるように私は、ロックを解除しないでしょう。この場合エラーの場合のフロックのリリース?

successfully acquired flock for FILEHANDLER  # line 1 
some error or maybe simply a call to exit()  # line 2 
close FILEHANDLER (which also releases the lock) # line 3 

を、ロックがこれまでにリリースされますオペレーティングシステムによって「ねえ、ロックを取得したスクリプトがクラッシュしました」と表示され、ロックが解除されますか?すぐにロックを解除しますか?また、スクリプトごとに1つのPerlインスタンスが実行されているため、ロックを解除せずにクラッシュ/ストップしたスクリプトは明らかです。

答えて

24

この場合、オペレーティングシステムによってロックが解放されていますか?
「ねえ、ロックを取得したスクリプトがクラッシュしました」と表示され、ロックが解除されますか?
すぐにロックを解除しますか?

これらの質問はすべてシステムによって異なります。 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

注:親プロセスがロックを取得してロックする前にロックを放棄しない場合、親が終了しても子プロセスは同じロックを持ちます。

+3

すばらしい解答、ありがとう!また、短くてもsoulSurfer2010に感謝しますが、まだ正解です。 –

1

プログラムが終了すると、OSはプログラムによって取得されたすべてのロックを自動的に解放し、プログラムによって開かれたすべてのファイルを閉じます。

+0

あなたが正しいという証拠がない限り、この回答は役に立たない。 –

関連する問題