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

  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

  7. #7
    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
    la redirection semble en effet être gérée en amont...
    je ne vois pas trop comment on pourrait s'en sortir du coup

  8. #8
    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
    Comme je voyais le subprocess de la même manière qu'un thread, je ne m'étais pas préoccupé du temps prit par la boucle while.

    J'ai donc, vérifié la chose:

    le travail : importer 126 photos de mon appareil photo vers mon dossier images en mode graphique et en utilisant gPhoto2 ce qui explique l'usage de subprocess. Le protocole PTP est lent et les photos ont une taille de +- 2 Mo.

    Sans while, avec .communicate, donc les infos d'avancement de l'import s'affichent dans la console :

    287.974 sec

    Avec la boucle while et les infos s'affiche dans l'interface :

    284.899 sec

    On peut raisonnablement supposer que les trois secondes de différence sont dues au fait que le cpu n'avait pas que ça à faire de sa journée.

    Donc, le temps est équivalent.

    vincent

  9. #9
    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 le test VinsS, c'est très sympa!

    Apparemment, on se dirige plutôt vers une sortie fichier histoire de pas trop perdre de temps... C'est dommage de s'orienter vers la solution de facilité, mais bon, c'est pas moi qui décide sur ce coup

    Merci encore

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