2009-02-13 24 views
38

Estoy creando un pequeño tablero para un usuario que le permitirá ejecutar trabajos específicos. Estoy usando Django, así que quiero que él pueda hacer clic en un enlace para comenzar el trabajo y luego devolverle la página con un mensaje de que el trabajo se está ejecutando. Los resultados del trabajo se le enviarán por correo electrónico más tarde.¿Cómo ejecuto otro script en Python sin esperar a que termine?

Creo que se supone que debo usar subprocess.Popen pero no estoy seguro de eso. Así, en pseudocódigo, esto es lo que quiero hacer:

if job == 1: 
    run script in background: /path/to/script.py 
    return 'Job is running' 
+0

posible duplicado de ** [Iniciando un proceso de fondo en python] (http://stackoverflow.com/questions/1196074/starting-a-background-process-in-python) ** y de ** [Cómo iniciar y ejecutar un script externo en el fondo?] (http://stackoverflow.com/questions/1605520/how-to-launch-and-run-external-script-in-background) ** – olibre

Respuesta

61
p = subprocess.Popen([sys.executable, '/path/to/script.py'], 
            stdout=subprocess.PIPE, 
            stderr=subprocess.STDOUT) 

que comenzará el subproceso en segundo plano. Tu script seguirá funcionando normalmente.

Lea la documentación here.

+0

nosklo: Gracias. ¿Cómo pasaría argumentos al guión? – sheats

+3

Elementos adicionales en la lista pasados ​​como el primer argumento. La documentación vinculada es útil y está vinculada a ella por una razón. –

+0

En un entorno que no es de Windows, también puede consultar os.fork –

3

subprocess.Popen es de hecho lo que estás buscando.

1

Aunque si encuentra que desea comenzar a comunicar una gran cantidad de información entre el subproceso y el elemento primario, puede considerar un hilo o un marco RPC como Twisted.

Pero lo más probable es que sean demasiado pesadas para su aplicación.

6

Ejecutar esto a través de una cola de mensajes es definitivamente el camino a seguir si está pensando en escalar a largo plazo. Envíe un mensaje a la cola que se ejecuta constantemente en segundo plano y escriba controladores de trabajo para tratar los diferentes tipos de mensajes.

Dado que estás usando Django, creo que Beanstalkd es una muy buena opción. Here's un bonito tutorial sobre el tema. El primer comentario en ese artículo también tiene algunos buenos consejos.

Personalmente he rodado con un servidor de cola personalizado en memoria escrito en Erlang, con enlaces de Python escritos en C. Pero redis parece que podría funcionar como un gran candidato para futuras necesidades de cola/mensajería. ¡Espero que esto ayude!

+3

apio (http://pypi.python.org/pypi/celery) también sería un buen partido para esto.Utiliza RabbitMQ (para la persistencia del mensaje, un beanstalkd backend para zanahoria es ciertamente posible si alguien tiene el tiempo). El tutorial beanstalkd solo resuelve uno de los problemas, enviando mensajes, pero deja realmente la tarea en ejecución para el lector. – asksol

Cuestiones relacionadas