2010-10-19 19 views
24

A veces, mi llamada al sistema entra en un estado interminable. Para evitar que quiera salir de la llamada después de un período de tiempo específico.¿Cómo puedo especificar el límite de tiempo de espera para la llamada al sistema Perl?

¿Hay alguna manera de especificar un límite de tiempo de espera para system?

system("command", "arg1", "arg2", "arg3"); 

Quiero que el tiempo de espera que se aplicará a partir del código de Perl para la portabilidad, y no usar algunas funciones específicas del sistema operativo como ulimit.

+1

Este es un duplicado más veces de las que puedo contar: http://stackoverflow.com/questions/2679582/how-can-i-kill-a-perl-system-call-after-a -timeout http://stackoverflow.com/questions/1962985/how-can-i-timeout-a-forked-process-that-might-hang http://stackoverflow.com/questions/2423288/ways-to-do -timeouts-in-perl http://stackoverflow.com/questions/3427401/perl-make-script-timeout-after-x-number-of-seconds http://stackoverflow.com/questions/1165316/how-can -i-limit-the-time-spent-in-a-specific-section-of-a-perl-script son solo algunas. – Ether

Respuesta

27

Ver la función alarm. Ejemplo de vaina:

eval { 
    local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required 
    alarm $timeout; 
    $nread = sysread SOCKET, $buffer, $size; 
    alarm 0; 
}; 
if ([email protected]) { 
    die unless [email protected] eq "alarm\n"; # propagate unexpected errors 
    # timed out 
} 
else { 
    # didn't 
} 

hay módulos en CPAN que envuelven estos hasta un poco más agradable, por ejemplo: Time::Out

use Time::Out qw(timeout) ; 

timeout $nb_secs => sub { 
    # your code goes were and will be interrupted if it runs 
    # for more than $nb_secs seconds. 
}; 

if ([email protected]){ 
    # operation timed-out 
} 
+0

Esto parece funcionar, pero el problema es que el comando ejecutado a través de la llamada al sistema continuará ejecutándose, incluso si el proceso principal de Perl ya ha fallecido. ¿Alguien sabe cómo obtener el identificador de proceso/identificador del proceso ejecutado por la llamada al sistema para que podamos eliminarlo antes de que finalice el script de Perl? – antred

+1

@antred - Para obtener la identificación del proceso, entonces necesita volver a escribir usando ['fork'] (http://perldoc.perl.org/perlfork.html) en lugar de [' system'] (http: // perldoc. perl.org/functions/system.html). Eche un vistazo a módulos como IPC :: Cmd & IPC :: Run para hacer esto más fácil (en este contexto). – draegtun

13

Le ofrecemos IPC::Run 's método de ejecución en lugar del sistema. y establecer un tiempo de espera.

3

¿Qué tal System::Timeout?

Este módulo se extiende a system para permitir el tiempo de espera después de los segundos especificados.

timeout("3", "sleep 9"); # timeout exit after 3 seconds 
+0

Las respuestas de solo enlace no son útiles cuando el contenido se mueve o cambia. Incluya las partes relevantes del enlace en su respuesta, adaptadas para que coincidan con la pregunta. – miken32

+0

Un enlace a una solución potencial siempre es bienvenido, pero por favor [agregue contexto alrededor del enlace] (http://meta.stackexchange.com/a/8259) para que los demás usuarios tengan una idea de qué es y por qué está allí . Siempre cite la parte más relevante de un enlace importante, en caso de que el sitio objetivo no esté disponible o esté permanentemente fuera de línea. Tenga en cuenta que ser un poco más que un enlace a un sitio externo es una posible razón para [¿Por qué y cómo se eliminan algunas respuestas?] (Http://stackoverflow.com/help/deleted-answers). – FelixSFD

+1

@ miken32 Editado. – melpomene

Cuestiones relacionadas