2010-12-07 9 views
1

J'ai essayé à la fois pexpect et subprocess.Popen de python pour appeler un processus d'arrière-plan externe à long terme (ce socket d'utilisation de processus pour communiquer avec des applications externes), avec les détails suivants.question sur pexpect en python

  1. subprocess.Popen (launchcmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE) Cela fonctionne très bien. Je n'ai pas besoin de faire autre chose. Cependant, parce que je dois obtenir la sortie immédiatement, je choisis pexpect pour éviter le problème de tampon du fichier pipe.

  2. obj = pexpect.spawn (launchcmd, délai d'attente = Aucun) après le lancement de processus externe, j'utiliser un autre thread « readline » pour lire la sortie du processus lancé « obj », et tout est ok. Obj = pexpect.spawn (launchcmd, timeout = None) Après le lancement d'un processus externe, je n'ai rien fait de plus, c'est-à-dire, laissez-le simplement là. Bien que, en utilisant la commande "ps -e" je peux trouver le processus lancé, mais le processus lancé semble bloqué et ne peut pas communiquer dans les sockets avec d'autres applications.

OK. Pour être plus précis, j'ai mis quelques exemples de code pour formuler ma question.

import subprocess 
import pexpect 
import os 

t=1 
while(True): 
    if(t==1): 
     background_process="./XXX.out" 
     launchcmd = [background_process] 
     #---option 3-------- 
     p=pexpect.spawn(launchcmd, timeout=None) # process launced, problem with socket. 
     #---option 1-------- 
     p=subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # process launced, everything fine 
     t=0 

Quelqu'un peut-il me dire ce qui ne va pas avec la 3ème option? Et si cela est dû au fait que je n'ai pas utilisé un thread séparé pour manipuler la sortie, pourquoi la 1ère option fonctionne avec subprocess.popen? Je soupçonne qu'il y a quelque chose qui ne va pas avec pexpect pour lancer un processus en utilisant socket, mais je ne suis pas sûr, d'autant plus que l'option 2 fonctionne bien.

+0

Je pense que vous pouvez confondre la différence entre la tuyauterie et les tampons - un tuyau est juste un conduit, si elle est tamponnée ou non dépend de l'application c'est écrit à lui (avant que vous lisiez). Readline est mise en mémoire tampon - jusqu'à ce que vous obteniez un retour à la ligne. read() est mis en mémoire tampon car il lit jusqu'à obtenir un EOF. Le premier exemple que vous fournissez devrait être bon, s'il y a des données à lire, vous l'obtiendrez, mais si votre launchcmd est en mémoire tampon, il ne sera pas instantané. – synthesizerpatel

+0

salut, synthesizerel, merci pour ton commentaire. mais je pense que cela n'aide pas vraiment ma question. – pepero

+0

@synthesizerpatel: sur Linux, un tube est tamponné, par le noyau. Cette mise en mémoire tampon est indépendante du tampon en cours de traitement et jusqu'à présent, je n'ai pas trouvé le moyen de l'éteindre. –

Répondre

1

Je pense que vous rendez cela trop compliqué. Oui, c'est une bonne idée d'utiliser un pty au lieu d'un pipe pour communiquer avec le processus d'arrière-plan parce que la plupart des applications reconnaissent les périphériques tty/pty et passent à une sortie sans tampon (ou au moins linéaire).

Mais pourquoi pexpect? Utilisez simplement le module pty de Python. Appelez d'abord openpty pour obtenir des handles de fichiers, puis utilisez Popen pour générer le processus. Exemple de code se trouve dans la question suivante (la réponse avec la coche verte) Python Run a daemon sub-process & read stdout