[Python] Communication avec un subprocess

Communication avec un subprocess [Python] - Python - Programmation

Marsh Posté le 17-11-2009 à 09:28:45    

Bonjour à tous !
 
Je suis actuellement en train de créer une sorte de chaine de calcul afin d'automatiser un processus de conversion de données, géré par un script Python global. Un des maillons de cette chaîne est un petit executable (compilé en fortran d'après mes infos) que j'aimerais donc intégrer au script global.
Je me suis un peu renseigné et j'ai donc découvert les fonctions popen et communicate pour gérer les subprocess : ça marche très bien pour les modules que j'utilise qui font leur moulinette dans leur coin, mais j'ai un problème avec le fortran que j'ai évoqué au dessus puisque celui-ci demande des informations à l'utilisateur, en gros 3 infos façon "raw_input", mais en fortran  :) , pour faire son boulot. J'utilise le code suivant :

Code :
  1. sub1 = subprocess.Popen(args="moulinette.exe", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  2. print sub1.communicate("Athena" )


Et donc quand je lance le python global, au moment d'arriver à cette moulinette, le python se met en attente, mais rien ne s'affiche, et je ne peux rien taper, alors que j'aimerais pouvoir l'utiliser comme si j'avais lancé directement l'executable moulinette.exe.
J'ai cherché un peu sur internet, et je suis tombé sur des stdout/stdin.write, des histoires de "deadlock" ou encore de buffer à vider avec une certaine fonction "flush", mais même si j'ai à peu près compris ces principes, je n'ai pas réussi à obtenir ce que je voulais pour ma chaîne de calcul.
Voilà ce que j'aimerais donc : le python parent lance le fortran fils, lorsqu'il reçoit une demande d'input du fils il affiche tout ce qu'il a reçu entre temps (la question "Entrer la premiere info :" en l'occurence), attend un réponse de l'utilisateur pendant que le fils est en pause, une fois celle-ci renseignée, le parent l'envoie au fils qui continue sa bidouille jusqu'à la deuxième question, et ainsi de suite...
Je n'ai pas l'impression de trop rêver en demandant ça au Python, donc je dois mal m'y prendre...Y'aurait-il donc quelqu'un pour m'éclairer un peu sur la façon de faire ? Merci beaucoup !

Reply

Marsh Posté le 17-11-2009 à 09:28:45   

Reply

Marsh Posté le 30-11-2009 à 19:25:00    

bionix a écrit :

Voilà ce que j'aimerais donc : le python parent lance le fortran fils, lorsqu'il reçoit une demande d'input du fils il affiche tout ce qu'il a reçu entre temps (la question "Entrer la premiere info :" en l'occurence), attend un réponse de l'utilisateur pendant que le fils est en pause, une fois celle-ci renseignée, le parent l'envoie au fils qui continue sa bidouille jusqu'à la deuxième question, et ainsi de suite...


Impossible.
 
Lorsqu'un process parent appelle un processus enfant (via pipe ou system() ou autre outil), c'est tout le processus enfant qui s'exécute intégralement. Si l'enfant attend des inputs claviers, alors l'enfant sera en pause tant que l'utilisateur n'aura pas entré son info au clavier.
Une fois que l'enfant a tout fini, alors le parent reprend la main. Et c'est pas un phénomène Python mais général à la gestion des processus.
 
Et s'il t'arrivait d'avoir envie de lancer l'enfant en lui redirigeant son stdin (comportement propre aux unixiens), alors chaque fois que l'enfant aura besoin d'une info clavier, il viendra la piocher dans le stdin redirigé (sous-entendu "redirigé à partir d'une grosse banque de donnée" ) mais tu ne pourra pas forcer l'enfant à renvoyer la demande au papa et à se mettre en pause en attendant. Ou alors tu programmes entièrement le papa et le fiston en les faisant communiquer via pipe, socket pour que, dès que l'enfand a besoin d'une info, il transmette la demande au papa et attende sa réponse. C'est un truc à programmer soi-même parce que ce n'est pas le comportement standard d'un processus.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 16-12-2009 à 11:05:50    

Ok, merci pour l'éclaircissement en tout cas !
 
Finalement à force de chercher j'ai découvert une autre façon, super simple mais dont je n'avais jamais entendu parlé, à savoir l'utilisation des redirections avec les caractères ">" et "<"...
J'ai donc recopié les questions du fils dans le python parent, qui écrit alors un fichier texte qui sert ensuite de stdin au fils... Je sais pas si c'est une façon très propre, mais ça marche nickel :)

Reply

Marsh Posté le 25-12-2009 à 21:50:35    

bionix a écrit :

Finalement à force de chercher j'ai découvert une autre façon, super simple mais dont je n'avais jamais entendu parlé, à savoir l'utilisation des redirections avec les caractères ">" et "<"...


Amusant. C'est la base de la communication sous Unix. Ptet que tu devrais commencer par apprendre certaines notions...
 

bionix a écrit :

J'ai donc recopié les questions du fils dans le python parent, qui écrit alors un fichier texte qui sert ensuite de stdin au fils... Je sais pas si c'est une façon très propre, mais ça marche nickel :)


Bon, ça me semble quand-même flou. Car quand le fils envoie sa question au papa, il doit ensuite se terminer pour que le papa puisse reprendre la main afin de poser sa question à l'utilisateur. Puis une fois que le papa a sa réponse, s'il relance le fils il faut qu'il sache qu'il n'a plus besoin de poser la question. Ou alors il ne lance pas le même fils. Bref je suis un peu perdu sur ta soluce.
 
Toutefois, puisque t'utilises un fichier texte qui sert de stdin au fils, c'est exactement comme si tu faisais sous unix
commande 1 >fichier
commande 2 <fichier
 
Ben ces deux lignes peuvent être remplacées par une simple instruction "commande 1 | commande 2". Les datas de la commande 1 deviennent stdin de la commande 2 mais tout se passe en mémoire grace au pipe. Ca évite la création d'un fichier sur disque. Ptet que tu peux appliquer cette idée à ton truc...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed