2010-10-19 17 views
24

A volte la mia chiamata di sistema entra in uno stato senza fine. Per evitare che io voglia essere in grado di interrompere la chiamata dopo un determinato periodo di tempo.Come è possibile specificare un limite di timeout per la chiamata di sistema Perl?

C'è un modo per specificare un limite di timeout a system?

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

Voglio il timeout importati da al codice Perl per la portabilità, e non l'utilizzo di alcune funzioni specifiche del sistema operativo come ulimit.

+1

Questo è un duplicato più volte di quanto posso contare: 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-il-tempo-trascorso-in-uno-specifico-sezione-di-uno-script-perl sono solo alcuni. – Ether

risposta

27

Vedere la funzione alarm. Esempio da pod:

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 
} 

Non ci sono moduli su CPAN che avvolgono questi un po 'più bene, per esempio: 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

Sembra funzionare, ma il problema è che il comando eseguito tramite la chiamata di sistema continuerà a essere eseguito, anche se il processo Perl genitore è già morto. Qualcuno sa come ottenere l'id/handle del processo eseguito dalla chiamata di sistema in modo da poterlo uccidere prima che lo script Perl termini? – antred

+1

@ antred - Per ottenere l'id del processo, è necessario riscriverlo utilizzando ['fork'] (http://perldoc.perl.org/perlfork.html) anziché [' system'] (http: // perldoc. perl.org/functions/system.html). Dai un'occhiata a moduli come IPC :: Cmd e IPC :: Esegui per semplificare (in questo contesto). – draegtun

13

È possibile utilizzare IPC::Run 's metodo run, invece di sistema. e impostare un timeout.

3

Che ne dici di System::Timeout?

Questo modulo estende system per consentire il timeout dopo i secondi specificati.

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

Le risposte di solo collegamento non sono utili quando il contenuto si sposta o cambia. Includi le parti pertinenti del link nella tua risposta, su misura per abbinare la domanda. – miken32

+0

Un collegamento a una potenziale soluzione è sempre il benvenuto, ma per favore [aggiungi contesto intorno al link] (http://meta.stackexchange.com/a/8259) così i tuoi utenti avranno un'idea di cosa sia e perché è lì . Citare sempre la parte più rilevante di un link importante, nel caso in cui il sito target non sia raggiungibile o sia permanentemente offline. Considera che essere appena più di un link a un sito esterno è una possibile ragione per [Perché e come vengono eliminate alcune risposte?] (Http://stackoverflow.com/help/deleted-answers). – FelixSFD

+1

@ miken32 Modificato. – melpomene

Problemi correlati