Communiqué de troupeau en cas d'erreurs?
Question
Imaginez la suite du code Perl (ici en pseudo-code):
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
Dans ce cas, je ne serais pas libérer le verrou, comme le script Perl extrémités de la ligne 2.Dans ce cas, la serrure est jamais sorti par le système d'exploitation?Voit-il "hey, le script qui a acquis le verrou s'est écrasé" et libérer le verrou?Est-il la libérer immédiatement?Aussi, est-il un Perl instance en cours d'exécution pour chaque script, de sorte qu'il est clair que le script s'est écrasé/arrêté sans relâcher le verrou?
La solution
Dans ce cas, la serrure est jamais sorti par le système d'exploitation?
Voit-il "hey, le script qui a acquis le verrou s'est écrasé" et libérer le verrou?
Est-il la libérer immédiatement?
L'ensemble de ces questions dépendent du système.Perl 5 ne pas mettre en œuvre une fonction de verrouillage de fichier, il fournit une interface commune pour flock(2)
, fcntl(2)
de verrouillage, ou lockf(3)
(selon ce qui est disponible dans les OS).Il peut aussi y avoir une différence entre ce qui se passe lorsqu'un programme se termine, de segmentation, ou est tué avec un sigkill.
Un test rapide sous Linux montre qu'un verrou est supprimée dans des conditions normales conditions de sortie:
$ 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
Nous allons voir ce qui se passe lorsque nous 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.
Pour obtenir une erreur de segmentation, nous aurons besoin de l'accès à C, je suis en utilisant Inline
pour l'obtenir:
$ 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
Et enfin, voici ce qui se produit lorsqu'un programme est envoyé 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
À partir de ces expériences, nous pouvons voir que le verrou est libéré dans Linux pour chacun des cas, vous ont été concernés par.
Aussi, est-il un perl instance en cours d'exécution pour chaque script, de sorte qu'il est clair que le script s'est écrasé/arrêté sans relâcher le verrou?
Oui, Perl 5 a un perl
processus par le script.Même si vous avez la fourchette, l'enfant reçoit son propre perl
processus.Le filetage ne pas fournir un distinct perl
processus.
Note:si l'un des parents est d'une serrure et de ne pas l'abandonner avant le verrouillage, l'enfant aura la même serrure, même si le parent quitte.
Autres conseils
Lorsque le programme quitte le programme, le système d'exploitation libère automatiquement tous les verrous acquis par le programme et ferme tous les fichiers ouverts par le programme.