2010-03-05 15 views

risposta

38

StackOverflow non mi consente di eliminare la mia risposta poiché è accettata. Sta raccogliendo voti negativi poiché è in cima alla lista con una soluzione migliore sotto di esso. Se si utilizza un sistema GNU, utilizzare timeout come suggerito da @wRAR. Quindi, nella speranza che si fermerà down-voto, ecco come funziona:

timeout 1s ./myProgram 

È possibile utilizzare s, m, h o d per secondi (il default se omesso), minuti, ore o giorni. Una caratteristica interessante qui è che è possibile specificare un'altra opzione (prima del 1s sopra) per ucciderlo con un SIGKILL dopo altri 30 secondi, nel caso non risponda al SIGTERM originale.

Uno strumento molto utile. Ora scorri verso il basso e fai salire la risposta @ wRAR.


Ai posteri, questa era la mia originale - inferiore - suggerimento, potrebbe essere ancora se qualche utilità per qualcuno.

Un semplice bash-script dovrebbe essere in grado di farlo per voi

./myProgram & 
sleep 1 
kill $! 2>/dev/null && echo "myProgram didn't finish" 

che dovrebbe farlo.

$! si espande nell'ultimo processo in background (tramite l'uso di &) e kill restituisce false se non ha eliminato alcun processo, quindi l'eco viene eseguito solo se effettivamente ha ucciso qualcosa.

2>/dev/null reindirizza lo stderr di kill, altrimenti verrebbe stampato qualcosa che ti diceva che non era in grado di terminare il processo.

È possibile aggiungere un -KILL o qualsiasi segnale che si desidera utilizzare per eliminare anche il processo.

EDIT
Come ephemient sottolineato, c'è una gara qui se i vostri finiture del programma e l'altro processo strappa il pid, otterrà uccisi invece. Per ridurre la probabilità che ciò accada, potresti reagire al SIGCHLD e non cercare di ucciderlo se ciò accade. C'è ancora la possibilità di uccidere il processo sbagliato, ma è molto remoto.

trapped="" 
trap 'trapped=yes' SIGCHLD 
./myProgram & 
sleep 1 
[ -z "$trapped" ] && kill $! 2>/dev/null && echo '...' 
+0

Questo ha funzionato .. grazie – Overdeath

+1

Potrebbe voler salvare 'PID = $!', Impostare un 'trap 'PID =' SIGCHLD', e' [-n $ PID] && kill $ pid', cosicché nel (improbabile) caso in cui il bambino esca e venga avviato un altro processo riutilizzando lo stesso PID, non si uccide lo spettatore innocente. – ephemient

+0

@ephemient: si, l'ho considerato anch'io. non eliminerà completamente la gara, ma certamente ridurrà la finestra. – falstro

3

si potrebbe lanciarlo in uno script di shell utilizzando &

your_program & 
pid=$! 
sleep 1 
if [ `pgrep $pid` ] 
    then 
    kill $pid 
    echo "killed $pid because it took too long." 
fi 

speranza si ottiene l'idea, io non sono sicuro che questo è corretto le mie capacità di shell bisogno di qualche aggiornamento :)

0

Se si dispone di le fonti, è possibile fork() all'inizio di main() e quindi fare in modo che il processo padre misuri il tempo e possibilmente uccida il processo figlio. Basta usare le chiamate di sistema standard fork(), waitpid(), kill(), ... forse alcuni standard di gestione del segnale Unix. Non è troppo complicato, ma richiede un certo sforzo.

È anche possibile scrivere qualcosa sullo shell, anche se dubito che sarà accurato rispetto al tempo di 1 secondo.

Se si desidera misurare l'ora, digitare time <cmd ...> sulla shell.

+0

Questo è stato il modo in cui ho pensato di farlo nel primo tempo. Ma ho bisogno che il programma funzioni senza accesso ai file sorgente. Grazie per la risposta – Overdeath

18

Forse il limite di tempo della CPU (ulimit -t/setrlimit(RLIMIT_CPU)) aiuterà?

+0

+1 per un approccio molto interessante! :) – falstro

+0

Come potrei verificare se il programma ha superato il tempo di esecuzione? – Overdeath

+0

@Overdeath: Probabilmente dovresti creare il tuo programma 'fork',' setrlimit' e 'waitpid', e poi controlla se è stato ucciso da un SIGXCPU. Puoi anche controllare il valore di ritorno del tuo programma, bash solitamente imposta '$?' Su qualcosa di alto quando viene ucciso da un segnale. Non so se è possibile determinare se è SIGXCPU però. – falstro

1

Ok, quindi basta scrivere un breve programma C che fork s, chiamate execlp o qualcosa di simile nel bambino, misura il tempo nel genitore e kill s del bambino. Dovrebbe essere facile ...

88

Ah bene. timeout(1).

DESCRIZIONE
Avviare Command, e uccidere, se ancora in esecuzione dopo DURATA.

+1

Si prega di commentare il downvoting. – wRAR

+5

Penso che ci sia stato un equivoco qui. un semplice "timeout uomo" può mostrare che questa risposta è la risposta più precisa (anche se piuttosto concisa) alla domanda in questione. Il timeout –

+4

(1) si trova in coreutils GNU. – minopret

1
tail -f file & pid=$! 
sleep 10 
kill $pid 2>/dev/null && echo '...' 
Problemi correlati