In tal caso, la serratura è stata rilasciata dal sistema operativo?
Si vede "hey, lo script che ha acquisito il blocco si è bloccato" e rilascia il blocco?
Rilascia immediatamente il blocco?
Tutte queste domande dipendono dal sistema. Perl 5 non implementa una funzione di blocco dei file, ma fornisce un'interfaccia comune al blocco flock(2)
, fcntl(2)
o lockf(3)
(a seconda di ciò che è disponibile nel sistema operativo). Potrebbe anche esserci una differenza tra ciò che accade quando un programma esce, segfaults o viene ucciso con un sigkill.
Un test rapido sotto Linux dimostra che un blocco è stato rimosso in condizioni di uscita normali:
$ 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
Vediamo cosa succede quando 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.
per ottenere un segfault, avremo bisogno accesso a C, sto usando Inline
per ottenerlo:
$ 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
E, infine, ecco cosa succede quando un programma viene inviato 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
Da questi esperimenti, possiamo vedere che il blocco viene rilasciato in Linux per ognuno dei casi riguardavano.
Inoltre, c'è un caso perl esecuzione per ogni script, in modo che sia chiaro che lo script è schiantato/fermato senza rilasciare la serratura?
Sì, Perl 5 ha un perl
processo per ogni script. Anche se si forchetta, il bambino ottiene il proprio processo perl
. Threading non fornisce un processo separato perl
.
Nota: se un processo genitore ottiene un blocco e non lo arresta prima del blocco, il bambino avrà lo stesso blocco anche se il genitore esce.
risposta dettagliata impressionante, grazie mille! anche grazie a soulSurfer2010 per la risposta breve, ma comunque corretta e informativa! –