Como parar um subprocesso python que está executando testes de unidade imediatamente?Terminar e matar não está funcionando

StackOverflow https://stackoverflow.com/questions/3302910

Pergunta

Eu tenho uma GUI Tkinter executando dois threads, o piso principal da GUI e um thread de trabalho.O thread de trabalho cria um subprocesso usando o seguinte código:

myProcess = subprocess.Popen(['python', '-u', 'runTests.py'],  
                         stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT)

O arquivo runTests.py faz algumas configurações e depois executa um arquivo de teste de unidade usando o seguinte comando:

execfile('myUnitTests.py')

O arquivo myUnitTests.py contém vários testes de unidade, alguns que levam mais de cinco minutos para serem executados.Na GUI, clico em um botão para interromper a execução dos testes.Isso, por sua vez, faz com que o thread de trabalho envie um sinal para interromper o subprocesso:

myProcess.terminate()

O comando terminar não interrompe o processo imediatamente, ele espera até que o teste de unidade atual termine de ser executado e então encerra o processo?Eu tentei usar os.kill mas obtenho os mesmos resultados que com terminate().

Alguma ideia de como posso tornar meu programa mais responsivo para que ele elimine o subprocesso imediatamente?

Foi útil?

Solução

A documentação do Python [ http://docs.python.org/library/signal.html ] diz:

  • Embora os manipuladores de sinal Python sejam chamados de forma assíncrona no que diz respeito ao usuário Python, eles só podem ocorrer entre as instruções “atômicas” do interpretador Python.Isso significa que os sinais que chegam durante longos cálculos implementados exclusivamente em C (como correspondências de expressões regulares em grandes corpos de texto) podem ser atrasados ​​por um período de tempo arbitrário.

Portanto, se o seu teste unitário de cinco minutos estiver fazendo "um longo cálculo implementado puramente em C", e seu equipamento de teste de unidade instala um manipulador para SIGTERM, esse é o seu problema.Se sim, tente myProcess.kill em vez de myProcess.terminate (ou, se você não tiver 2,6, myProcess.send_signal(9)). SIGKILL não pode ser capturado no espaço do usuário e deve ter efeito imediato.

Aviso:quaisquer ações de limpeza que deveriam ser executadas na saída da estrutura de teste de unidade não serão executadas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top