Domanda

Immagina il seguente codice perl (qui in codice pseudo):

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
.

In questo caso non rilascerò il blocco, poiché lo script perl termina in linea 2. In tal caso, è il blocco mai rilasciato dal sistema operativo?Vedi "Ehi, lo script che ha acquisito il blocco si è schiantato" e rilascia il blocco?Rilascia immediatamente il blocco?Inoltre, esiste un'istanza perl in esecuzione per ogni script, in modo che sia chiaro quale script si è schiantato / arresto senza rilasciare il blocco?

È stato utile?

Soluzione

.

In tal caso, è il lucchetto mai rilasciato dal sistema operativo?
Vedi "Ehi, lo script che ha acquisito il blocco si è schiantato" e rilascia il blocco?
Rilascia immediatamente il blocco?

Tutte queste domande sono dipendenti dal sistema. Perl 5 non implementa una funzione di blocco del file, fornisce solo un'interfaccia comune a flock(2), bloccaggio 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 uscita, segfault o viene ucciso con un sigkill.

Un test rapido sotto Linux mostra che un blocco viene 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 di accedere 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 ciascuno dei casi con cui sei interessato.

.

Inoltre, esiste un'istanza perl in esecuzione per ogni script, in modo che sia chiaro quale script si è schiantato / interrotto senza rilasciare il blocco?

Sì, Perl 5 ha un processo perl per script. Anche se si è forcella, il bambino ottiene il proprio processo perl. La filettatura non fornisce un processo di generazione di perl separato.

Nota: se un processo genitore ottiene un blocco e non si arrende prima di bloccare, allora il bambino avrà lo stesso blocco anche se il genitore esce.

Altri suggerimenti

Quando il programma esce, il sistema operativo rilascia automaticamente tutte le serrature acquisite dal programma e chiude tutti i file aperti dal programma.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top