2010-07-16 8 views
1

J'essaye de faire communiquer deux processus en utilisant un tuyau. Je l'ai fait dans le processus parent:faire des programmes python "chat" via pipe

process = subprocess.Popen(test, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

process.stdin.write("4\n"); 
output = process.stdout.read() 
print output 

et dans le processus de l'enfant:

inp = raw_input() 
integer = int(inp) 
print integer**2 
while(True): 
    pass 

j'attendre le processus parent pour imprimer 16 ... Malheureusement, il reste suspendu sans rien imprimer. Le remplacement de la boucle infinie par un arrêt pendant 5 secondes fait que le processus parent reste inactif pendant 5 secondes et APRES cette impression 16. Cela montre que le processus parent n'obtient la sortie de l'enfant qu'après son exécution.

Je voudrais savoir s'il est possible d'obtenir des informations avant la fin des programmes. Mon idée est d'aller passer des informations via ce canal, d'obtenir des entrées, de les traiter et de sortir le résultat dans le canal, afin que l'autre puisse continuer le traitement.

Une aide? Merci,

Manuel

+3

Avez-vous essayé le rinçage du flux lorsque vous écrivez le ' "4 \ n" '? –

+0

Oui, ce n'est pas le problème. Le processus fils obtient effectivement ce 4, et je l'ai vu parce que juste après avoir lu cette entrée, je l'écris dans un fichier normal, puis entrer dans la boucle infinie. Le processus parent est celui qui se bloque dans la partie read(). –

+0

Par curiosité, pourquoi n'avez-vous pas utilisé 'sys.stdin.readline()' dans le processus fils? –

Répondre

2

Comme le suggère ndim, faire le folowing dans le parent:

process.stdin.write("4\n")  
process.stdin.flush()  
output = process.stdout.readline()  
print output 

Vous aurez aussi besoin de changer l'enfant:

inp = sys.stdin.readline() 
integer = int(inp) 
sys.stdout.write("%d\n", (integer ** 2,)) 
sys.stdout.flush() 

J'utilisé sys.stdin.readline et sys.stdout.write comme une question de style.

j'ai écrit 2 test programs et ils ont travaillé très bien avec python-2.6.4-27 sur Fedora 13.

+0

cela ne résout pas le problème, mais merci pour votre aide et conseils de style! –

+0

@Manuel: avez-vous essayé les nouveaux programmes? –

+0

Je l'avais résolu mais d'une manière très moche. Votre solution est simple et très propre! Merci beaucoup. (vous obtenez la marque de la solution parce que je vais mettre à jour mon code pour cela ...) –

4

Je vois un certain nombre de questions possibles:

a) Le processus de l'enfant ne fait débusque sa production et donc jamais envoie effectivement sa sortie à la société mère. B) Le processus parent exécute son appel read() avant que le processus fils ait réellement envoyé sa sortie (vidée de sa sortie).

c) Le processus parent effectue un blocage read() qui, jusqu'à EOF, signifie effectivement qu'il attend la sortie de l'enfant. Les docs subprocess.Popen devraient mentionner si cela peut être le cas.

d) L'appel read() du processus parent attend qu'un certain nombre d'octets (par exemple 1024) arrive avant son retour.

Le fait que le parent fasse beaucoup d'appels read(1) et que l'on réassemble les octets à mesure qu'ils arrivent règlera le problème. Ou en utilisant une API de communication de niveau supérieur, par ex. utiliser des datagrammes au lieu d'analyser des flux d'octets.

0

Vous devez utiliser select pour cela. Comme dans la méthode de communication du sous-processus. Il y a une discussion à ce sujet dans le python issue tracker.

Questions connexes