2010-03-11 15 views
15

Suelo utilizar el siguiente patrón para establecer un límite superior para el tiempo de ejecución de un fragmento de código en particular en Perl:Formas de hacer tiempos de espera en Perl?

my $TIMEOUT_IN_SECONDS = 5; 
eval { 
    local $SIG{ALRM} = sub { die "alarm\n" }; 
    alarm($TIMEOUT_IN_SECONDS); 
    # do stuff that might timeout. 
    alarm(0); 
}; 
if ([email protected]) { 
    # handle timeout condition. 
} 

Mis preguntas:

  • es esta la forma correcta de hacerlo?
  • ¿Hay alguna circunstancia en la que el tiempo de ejecución puede exceder $ TIMEOUT_IN_SECONDS, o el método anterior es a prueba de balas?
+1

Su evaluación es vulnerable a un error desagradable. Lea los documentos Try :: Tiny para obtener una explicación detallada: http://search.cpan.org/perldoc?Try::Tiny – daotoad

Respuesta

9

Probablemente quiera mirar Sys::SigAction. No lo he usado yo mismo, pero tiene some glowing reviews.

Una cosa a tener en cuenta es si "las cosas que podrían expirar" usan sleep o alarm sí mismo. Además, en el código de manejo de errores, supongo que está preparado para errores que no sean un tiempo de espera excedido.

+0

¿podría explicar el caso cuando la aplicación está utilizando el modo sleep? ¿Y como resolverlo? –

2

Tenga cuidado con el manejo de la señal. Perl recibe señales de forma asíncrona y pueden perderse o interferir entre sí si se recibe una señal mientras la devolución de llamada maneja otra señal. apoyo Win32

librerías para el manejo de eventos, es bastante regular en Perl (tengo que apoyar no cygwin Win32), por lo general, usar un simple bucle de sondeo para los tiempos de espera:

use Time::HiRes qw(sleep); 

sub timeout { 
    my $timeout = shift; 
    my $poll_interval = shift; 
    my $test_condition = shift; 
    until ($test_condition->() || $timeout <= 0) { 
    $timeout -= $poll_interval; 
    sleep $poll_interval; 
    } 
    return $timeout > 0; # condition was met before timeout 
} 

my $success = timeout(30, 0.1, \&some_condition_is_met); 

El temporizador de apagado puede configurarse fácilmente por el usuario o la persona que llama y, a menos que esté haciendo un bucle extremadamente cerrado o tenga múltiples llamadas esperando en el bucle (donde puede terminar con una carrera o un bloqueo), es un método simple, confiable y cruzado -forma de plataforma para implementar un tiempo de espera.

También tenga en cuenta que la sobrecarga del ciclo significa que no puede garantizar que el tiempo de espera se cumpla por completo. $ test_condition, la disminución, la recolección de basura, etc. pueden interferir.

+1

Esto no responde la pregunta. Este código no logrará el mismo objetivo que el código de OP. Si some_condition_is_met() nunca regresa, el programa se bloqueará. –

4

También podría probar Time::Out. Me gusta la sintaxis y los tiempos de espera anidados son compatibles ..

+1

+1 Este módulo maneja todas las preocupaciones sobre los tiempos de espera anidados, etc. para usted, por lo que no tiene que preocuparse por todos los casos límite. Es para alarmar lo que try :: tiny es para evaluar. – mikew

+0

¿El módulo Time :: Out es seguro? En mi caso, necesito un tiempo de espera que se ejecuta por hilo en mi aplicación. – reedog117

+0

@ reedog117: No tengo ni idea ... –

Cuestiones relacionadas