IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Sortie standard invalide?


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut Sortie standard invalide?
    Bonjour,

    Dans le cadre d'un projet en R, je dois utiliser un package pour faire du multithreading: netWorkSpaces. Ce package repose sur du code Python, et là j'y connais plus rien.

    Le hic avec ce genre de fonctionnement, c'est que le moteur démarre N instances de R ("workers") mais il ne récupére que les sorties finales, pas les intermédiaires (typiquement, les "printf" ou autre "cat"), utiles au traçage du programme. Pour comprendre mon problème, voici rapidement l'architecture:

    Programme R
    |
    package nws / classe Sleigh
    |
    BackgroundLaunch.py qui lance N fois "Python RNWSleighWorker.py" via CreateProcess
    |
    Chaque script RNWSleighWorker.py lance une instance de R via subprocess.popen

    Cette architecture n'est pas modifiable et indépendante de ma volonté.

    Une solution basique est d'aller modifier le script python pour afficher une fenétre avec le processus. Pour cela, j'ai juste modifié une ligne dans RNWSleighWorker.py:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    p = subprocess.Popen(argv, stdin=open(tmpname), stdout=out,
                        stderr=subprocess.STDOUT)
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                 p = subprocess.Popen(argv, stdin=open(tmpname), stderr=subprocess.STDOUT,
                                      creationflags = win32process.CREATE_NEW_CONSOLE)
    Cela a pour effet d'afficher les N terminaux R enfant. Mais ces N terminaux restent désepèrement vides (cf pièce jointe)!
    Certes, l'argument "stdout" de subprocess.popen n'est pas assigné et donc est probablement mis à None. Mais si:
    - stdout = subprocess.STDOUT , alors la fenêtre fille n'est tout simplement pas lancée et il semble que Python perde la main sur le programme.
    - stdout = subprocess.PIPE : aucun changement (ça se lance mais n'affiche rien)
    - stdout = un handle sur fichier: ça fonctionne!

    Bref, quelque chose me fait dire que c'est ma méconnaissance du Python qui me bloque et m'empêche d'assigner la bonne valeur à stdout. Obtenir le comportement de base reste étonnament difficile...

    Merci

    Cordialement

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonsoir,

    dans le code Python, comment est définie la variable 'out' qui apparait comme valeur de l'argument 'stdout' ?

  3. #3
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Une façon plus "actuelle" d'utiliser subprocess:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    reply = subprocess.Popen(argv, 
                                    universal_newlines=True, 
                                    stdout=subprocess.PIPE).communicate()
    Toutefois ici, .communicate() ne libérera les messages que lorsque le process sera terminé, ce qui ne semble pas ce que tu désires. on peut récupérer les messages intermédiaires de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    def my_process(bind):
        reply = subprocess.Popen(argv, universal_newlines=True, 
                                        stdout=subprocess.PIPE)
     
                while 1:
                    text = reply.stdout.readline()
                    if text == '' and reply.poll() != None: 
                        break
                    if type(text) == str:
                        # Ici tu place l'usage de txt dans bind
    Note qu'il est indispensable de supprimer .communicate()

    Donc ici, bind est une instance de l'objet dans lequel doivent apparaître les messages,
    text edit, line edit, console, j'ignore ce que tu utilise mais si interface graphique il y a, cela fonctionnera sans problème.

    JE cherche un lien utile dans mon foutoir ...

    vincent

    edit : J'ai trouvé : http://www.doughellmann.com/PyMOTW/subprocess/

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Merci pour vos réponses.
    Effectivement, je n'ai pas précisé ce qu'est la variable "out". C'est un handle vers un fichier :
    quitte à valoir NULL (ou None je crois) dans certains cas.

    La solution de VinsS me plaît mais je n'ai pas l'impression qu'elle soit non-bloquante. En effet, le handle "p" retourné par subprocess est utilisé plus loin (notamment listé puis p.wait() ). Enfin, il me semble qu'une boucle while telle que proposée risque de consommer beaucoup de ressources, non?
    Quel est votre avis?

    Merci

    Cordialement

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonjour,

    le programme appelant gère peut être lui même les redirections. l'approche de VinsS est celle que j'utilise également lorsque que je veux rediriger vers autre chose qu'un fichier (avec un time.sleep en plus pour rendre la main au CPU).

    peut être que dans ton cas, il suffit juste de ne pas préciser de stdout et stderr dans la construction de ton process p. cela aura pour effet d'utiliser les sorties standard (respectivement sys.stdout et sys.stderr).

    sinon, regardes dans le fichier texte mentionné dans l'instruction:

    voir si tu n'aurais pas dedans les sorties qu'il te manque

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations forums :
    Inscription : Juin 2002
    Messages : 256
    Par défaut
    Salut Kango,

    Comme mentionné dans mon premier post, le fichier pointé par "out" contient bien les sorties manquantes. Le hic, c'est que quand je ne spécifie pas stdout ou/et stderr, rien ne s'affiche à l'écran!

    C'est ce qui fait que je suis partagé sur le fait que le programme appelant (par CreateProcess, pour rappel) redirige les sorties...

    Merci

    Cordialement

Discussions similaires

  1. PB sortie standard avec les PTHREAD !!!
    Par djspit dans le forum C++
    Réponses: 15
    Dernier message: 19/11/2004, 01h17
  2. [langage] sortie standard linux
    Par ebaynaud dans le forum Langage
    Réponses: 8
    Dernier message: 14/10/2004, 08h05
  3. rediriger la sortie standard vers un textarea
    Par gromite dans le forum Composants
    Réponses: 9
    Dernier message: 10/05/2004, 11h07
  4. Réponses: 5
    Dernier message: 24/12/2003, 09h49
  5. Réponses: 16
    Dernier message: 18/07/2003, 17h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo