2009-02-13 7 views
38

Je crée un petit tableau de bord pour un utilisateur qui lui permettra d'exécuter des tâches spécifiques. J'utilise Django donc je veux qu'il puisse cliquer sur un lien pour démarrer le travail, puis lui retourner la page avec un message indiquant que le travail est en cours. Les résultats du travail lui seront envoyés par courrier électronique plus tard.Comment exécuter un autre script en Python sans attendre qu'il se termine?

Je crois que je suis censé utiliser subprocess.Popen mais je ne suis pas sûr de cela. Donc, en pseudocode, voici ce que je veux faire:

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

duplication possible de ** [Démarrage d'un processus d'arrière-plan en python] (http://stackoverflow.com/questions/1196074/starting-a-background-process-in-python) ** et de ** [Comment lancer et exécuter un script externe en arrière-plan?] (http://stackoverflow.com/questions/1605520/how-to-launch-and-run-external-script-in-background) ** – olibre

Répondre

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

qui commencera le sous-processus en arrière-plan. Votre script continuera à fonctionner normalement.

Lire la documentation here.

+0

nosklo: Merci. Comment pourrais-je transmettre des arguments au script? – sheats

+3

Éléments supplémentaires dans la liste transmis en tant que premier argument. La documentation liée est utile et liée à une raison. –

+0

Dans un environnement autre que Windows, vous pouvez aussi consulter os.fork –

3

sous-processus.Popen est en effet ce que vous cherchez.

1

Bien que si vous trouvez que vous voulez commencer à communiquer un tas d'informations entre le sous-processus et le parent, vous pouvez envisager un thread, ou un framework RPC comme Twisted.

Mais très probablement ceux-ci sont trop lourds pour votre application.

6

L'exécution à travers une file d'attente de messages est définitivement le chemin à suivre si vous envisagez une mise à l'échelle à long terme. Envoyez un message à la file d'attente qui s'exécute constamment en arrière-plan et écrivez des gestionnaires de travaux pour gérer les différents types de messages.

Depuis que vous utilisez Django, je pense que Beanstalkd est un bon ajustement. Here's un joli tutoriel sur le sujet. Le premier commentaire dans cet article a également quelques bons conseils.

Personnellement, j'ai roulé avec un serveur de file d'attente en mémoire personnalisé écrit en Erlang, avec des liaisons Python écrites en C. Mais redis semble être un excellent concurrent pour les futurs besoins de mise en file d'attente/messagerie. J'espère que cela t'aides!

+3

céleri (http://pypi.python.org/pypi/celery) serait également un bon match pour cela.Il utilise RabbitMQ (pour la persistance du message, un backend beanstalkd pour carot est certainement possible si quelqu'un a le temps) Le tutoriel beanstalkd résout seulement l'un des problèmes, en envoyant des messages, mais quitte réellement l'exécution de la tâche comme un exercice pour le lecteur. – asksol

Questions connexes