2012-09-29 31 views
8

imaginar el siguiente código de Perl (aquí en pseudocódigo):Lanzamiento del lote en caso de errores?

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 

En este caso no me liberar el bloqueo, ya que el script Perl termina en la línea 2. En ese caso, es el bloqueo lanzado siempre por el sistema operativo? ¿Ve "hey, el guión que adquirió el candado se colgó" y suelta el candado? ¿Libera el bloqueo de inmediato? Además, ¿hay una instancia de Perl ejecutándose para cada script, para que quede claro qué script se bloqueó/detuvo sin soltar el bloqueo?

Respuesta

24

En ese caso, ¿la cerradura se ha liberado alguna vez por el sistema operativo?
¿Ve "hey, el guión que adquirió el bloqueo se colgó" y suelta el bloqueo?
¿Libera la cerradura de inmediato?

Todas estas preguntas dependen del sistema. Perl 5 no implementa una función de bloqueo de archivos, solo proporciona una interfaz común para flock(2), fcntl(2) de bloqueo, o lockf(3) (dependiendo de lo que está disponible en el sistema operativo). También puede haber una diferencia entre lo que sucede cuando un programa sale, segfaults o se mata con un sigkill.

Una prueba rápida en Linux muestra que un bloqueo se elimina bajo condiciones de salida normales:

$ 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 

Vamos a ver lo que sucede cuando 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. 

para obtener una violación de segmento, necesitaremos acceso a C, estoy usando Inline para obtenerlo:

$ 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 

Y, por último, aquí es lo que sucede cuando un programa se envía 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 

A partir de estos experimentos, se puede ver que el bloqueo se libera en Linux para cada uno de los casos que se referían a.

Además, ¿hay una instancia de Perl ejecutándose para cada script, para que quede claro qué script se bloqueó/detuvo sin soltar el bloqueo?

Sí, Perl 5 tiene una perl proceso por guión. Incluso si te bifurcas, el niño obtiene su propio proceso perl. Enhebrar no proporciona un proceso perl por separado.

Nota: si un proceso padre consigue un bloqueo y no renunciar a ella antes de bloquear, entonces el niño tendrá la misma cerradura incluso si las salidas de los padres.

+3

impresionante respuesta detallada, ¡muchas gracias! ¡también gracias a soulSurfer2010 por la respuesta breve, pero aún correcta e informativa! –

1

Cuando el programa finaliza, el sistema operativo libera automáticamente todos los bloqueos adquiridos por el programa y cierra todos los archivos abiertos por el programa.

+0

Esta respuesta no es útil sin ninguna evidencia de que tienes razón. –

Cuestiones relacionadas