Como faço para executar outro script em Python sem esperar que ele termine? [duplicado
-
23-08-2019 - |
Pergunta
Esta pergunta já tem uma resposta aqui:
- Como iniciar um processo de fundo no Python? 7 respostas
Estou criando um pequeno painel para um usuário que lhe permitirá executar trabalhos específicos. Estou usando o Django, então quero que ele possa clicar em um link para iniciar o trabalho e depois devolver a página de volta a ele com uma mensagem de que o trabalho está em execução. Os resultados do trabalho serão enviados por e -mail para ele mais tarde.
Eu acredito que devo usar subprocess.Popen
Mas não tenho certeza disso. Então, no pseudocódigo, eis o que eu quero fazer:
if job == 1:
run script in background: /path/to/script.py
return 'Job is running'
Solução
p = subprocess.Popen([sys.executable, '/path/to/script.py'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
Isso iniciará o subprocesso em segundo plano. Seu script continuará funcionando normalmente.
Leia a documentação aqui.
Outras dicas
Executar isso através de uma fila de mensagens é definitivamente o caminho a percorrer se você estiver pensando em escala de longo prazo. Envie uma mensagem para a fila que está executando constantemente em segundo plano e escreva manipuladores de emprego para lidar com os diferentes tipos de mensagens.
Desde que você está usando Django, eu acho BeansTalkd é um bom ajuste. Aqui está Um bom tutorial sobre o assunto. O primeiro comentário nesse artigo também tem algumas boas dicas.
Pessoalmente, eu rolei com um servidor de fila de memória personalizado escrito em Erlang, com ligação a Python escrita em C. mas Redis Parece que pode funcionar como um ótimo concorrente para futuras necessidades de filas/mensagens. Espero que isto ajude!
Subprocess.popen é realmente o que você está procurando.
Embora, se você achar que deseja começar a comunicar um monte de informações entre o subprocesso e o pai, convém considerar um thread ou estrutura de RPC como Twisted.
Mas provavelmente isso é muito pesado para o seu aplicativo.