Como tempo de restrição um programa é executado no Linux?

10

Eu tenho várias simulações para fazer, cada uma é invocada com python simulate.py <parameter list> . O problema com essas simulações é que algumas delas param sem quitar, o que me impede de executá-las em lote com um script simples.

O que eu preciso, é alguma forma de comando "run-time-constraint", que automaticamente mataria o processo (preferencialmente pressionando virtualmente Ctrl + C , mas acho que simples kill will faça o mesmo) depois de um tempo especificado, se o processo não tiver terminado normalmente.

É claro que posso escrever esse roteiro, mas suspeito que alguém já tenha feito isso antes de mim, então não preciso reinventar a roda gastando horas com os manuais ps , time e bash.

    
por Adam Ryczkowski 06.05.2013 / 13:14

4 respostas

12

Solução potencial # 1

Use o comando timeout :

$ date
Mon May  6 07:35:07 EDT 2013
$ timeout 5 sleep 100
$ date
Mon May  6 07:35:14 EDT 2013

Você também pode colocar um guarda no comando timeout para kill do processo, se ele não tiver parado após algum período de tempo também.

$ date
Mon May  6 07:40:40 EDT 2013
$ timeout -k 20 5 sleep 100
$ date
Mon May  6 07:40:48 EDT 2013

Isso vai esperar até 20 segundos após o processo sleep 100 ter parado, se ainda estiver em execução, então timeout enviará um sinal kill .

Solução potencial # 2

Uma maneira alternativa, embora o método mais arriscado seria o seguinte:

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

Encontrou essa técnica no Stack Overflow em uma pergunta intitulada: Limitando a tempo que um programa é executado no Linux . Especificamente, esta resposta .

OBSERVAÇÃO: Por um comentário deixado por @mattdm, o método acima pode ser arriscado, pois pressupõe que não houve nenhum novo processo iniciado desde o seu processo. Portanto, nenhum novo PID foi atribuído. Diante disso, essa abordagem provavelmente não deve ser usada, mas está aqui apenas como referência para uma abordagem geral do problema. O método timeout é a melhor opção do 2.

    
por 06.05.2013 / 13:21
4

Encontrei algo um pouco melhor do que timeout : timelimit .

Tem várias vantagens; uma é que o usuário pode abortar manualmente a execução pressionando "Ctrl + C".

O programa timelimit está disponível no repositório Debian.

    
por 06.05.2013 / 15:02
3

Você pode ajustar o tempo da CPU e outras coisas com ulimit , principalmente para o tempo da CPU:

$ ulimit -t 60      # limit to 60 seconds
$ program
    
por 06.05.2013 / 16:50
0

Bash usa uma variável chamada $BASHPID que pode ser usada em tal situação, por exemplo:

#!/bin/bash
do_face() {
    local parent=$1
    echo $BASHPID > pid
    sleep 10
    echo "Killing parent $parent"
    kill $parent
}

ME=$BASHPID
eval $(echo "do_face $ME &")
sleep 20 && kill $(cat pid) && echo "killed child $(cat pid)"
exit 1

Você pode alterar o argumento na chamada para sleep em do_face() para 100 em vez de 10 e ver o que acontece quando a criança demora muito para fazer suas tarefas. Apenas mude a chamada para dormir em do_face() para uma chamada para o seu executável e, se demorar muito, o script irá eliminá-la, 20 segundos é o valor limite neste exemplo. Parâmetros podem ser implementados para que isso se torne um script simples para chamar e possa ser chamado por outro script em lote ou qualquer outro. O manuseio dos arquivos pid para cada processo concorrente é um problema que precisa ser tratado, talvez use subdiretórios diferentes ...

NB: No GNU Linux sleep pode levar argumentos de ponto flutuante como sleep 0.1 para dormir por um décimo de segundo.

    
por 27.11.2014 / 01:29