2016-01-19 9 views
14

Uso crontask per eseguire regolarmente Rscript. Sfortunatamente, ho bisogno di farlo su una piccola istanza di aws e il processo potrebbe bloccarsi, costruendo sempre più processi uno sopra l'altro fino a quando l'intero sistema è in ritardo.Elimina tutti i processi R che si bloccano per più di un minuto

Mi piacerebbe scrivere un crontask per uccidere tutti i processi R che durano più di un minuto. I found another answer on Stack Overflow that I've adapted that I think would solve the problem. Mi sono inventato;

Ho copiato l'attività direttamente da htop, ma non funziona come previsto. Ottengo l'errore No such file or directory ma l'ho controllato alcune volte.

Ho bisogno di uccidere tutti i processi R che durano più di un minuto. Come posso fare questo?

+0

Sospetto che sia necessario "pkill" piuttosto che "killall". http: // superutente.it/questions/220517/how-to-kill-a-process-with-name-having-spaces – Jason

risposta

8

Si consiglia di evitare di uccidere i processi da un altro utente e cercare SIGKILL (kill -9) dopo SIGTERM (kill -15). Ecco uno script si potrebbe eseguire ogni minuto con un cron job:

#!/bin/bash 

PROCESS="R" 
MAXTIME=`date -d '00:01:00' +'%s'` 

function killpids() 
{ 
    PIDS=`pgrep -u "${USER}" -x "${PROCESS}"` 

    # Loop over all matching PIDs 
    for pid in ${PIDS}; do 
     # Retrieve duration of the process 
     TIME=`ps -o time:1= -p "${pid}" | 
       egrep -o "[0-9]{0,2}:?[0-9]{0,2}:[0-9]{2}$"` 

     # Convert TIME to timestamp 
     TTIME=`date -d "${TIME}" +'%s'` 

     # Check if the process should be killed 
     if [ "${TTIME}" -gt "${MAXTIME}" ]; then 
      kill ${1} "${pid}" 
     fi 
    done 
} 

# Leave a chance to kill processes properly (SIGTERM) 
killpids "-15" 
sleep 5 

# Now kill remaining processes (SIGKILL) 
killpids "-9" 
+0

Alcuni commenti: '$ USER' dovrebbe già utilizzare una variabile di shell utilizzabile. piping 'pgrep' in un semplice' xargs' è ridondante. Puoi risparmiare un po 'sull'elaborazione dell'output di 'ps' se usi le opzioni corrette:' ps -o time: 1 = -p $ {pid} 'ti darà solo il tempo per quel PID. – muru

+0

Non selezionerà tutti i processi che hanno 'R' nel loro nome? –

+1

@MiserableVariable l'opzione '-x' di' pgrep' dovrebbe essere usata, immagino. – muru

5

Penso che l'opzione migliore sia lo stesso con R. Non sono esperto, ma sembra che il pacchetto future consentirà l'esecuzione di una funzione in un separato thread. È possibile eseguire l'attività effettiva in un thread separato e nella thread principale sleep per 60 secondi e quindi stop().


Aggiornamento Precedente di answer user1747036 che raccomanda timeout è un'alternativa migliore.


La mia risposta originale

Questa domanda è più appropriato per superutente, ma qui ci sono un paio di cose sbagliate con

if [[ "$(uname)" = "Linux" ]];then 
    killall --older-than 1m \ 
    "/usr/lib/R/bin/exec/R --slave --no-restore --file=/home/ubuntu/script.R"; 
fi 
  • L'argomento name è il nome di immagine o percorso ad esso. Hai incluso i parametri ad esso pure

  • Se -s signal non è specificato killall invia SIGTERM cui il processo può ignorare. Sei in grado di uccidere uno script di lunga durata con questo sulla riga di comando? Potrebbe essere necessario SIGKILL/

Altro http://linux.die.net/man/1/killall

7

Perché implica un ulteriore processo ogni minuto con cron? Non sarebbe più semplice avviare R con timeout from coreutils, i processi verranno quindi automaticamente eliminati dopo l'ora selezionata.

timeout [option] duration command [arg]… 
+0

quindi sarebbe: '' 'timeout --kill-after = 1m Rscript/home/ubuntu/script.R''' – cylondude

+0

Quasi, qui ha funzionato con: timeout 60 Rscript/home/ubuntu/script. R In alternativa, è possibile testare con timeout time 60 Rscript /home/ubuntu/script.R – user1747036

Problemi correlati