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 :

Comportement mystérieux de multiprocessing


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut Comportement mystérieux de multiprocessing
    Bonjour,

    en faisant des essais avec le module multiprocessing, je suis tombé sur un comportement des plus bizarres et tout à fait contrariant !
    Voici un bout de code minimal qui met en évidence le problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    from multiprocessing import Process
     
    def f ( name ):
        for i in xrange( 10 ):
            print name,i
     
    p = Process(target=f, args=('from root',))
    p.start()
    p.join()
    Quand le process est lancé, c'est la catastrophe !
    Il part dans une en boucle infinie (en affichant plein de fois les 10 lignes attendues) en occupant tout le CPU et en affichant de temps en temps :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Unable to register TclNotifier window class
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    Qu'ai je fait de mal ?
    Qu'est qu'un comprend-il le fin mot de l'histoire ?

    Merci d'avance...
    Hadrien

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Par défaut
    Hello,
    Tout ce que je peux dire c'est que chez moi ça fonctionne correctement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    $ cat pro.py
    from multiprocessing import Process
     
    def f ( name ):
        for i in xrange( 10 ):
            print name,i
     
    p = Process(target=f, args=('from root',))
    p.start()
    p.join()
     
    $ python pro.py 
    from root 0
    from root 1
    from root 2
    from root 3
    from root 4
    from root 5
    from root 6
    from root 7
    from root 8
    from root 9
     
    $ python --version
    Python 2.6.5

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    J'ai essayé avec une console (cmd sous Windows) pour être sûr de ne pas tomber dans un pb d'outil de développement. Et ça ne fonctionne pas non plus (boucle infinie), sauf quand je change le code comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from multiprocessing import Process
     
    def f(name):
        for i in xrange( 10 ):
            print name,i
     
    if __name__ == '__main__':
        p = Process(target=f, args=('from root',))
        p.start()
        p.join()
    Ce qui m'a fait essayer ça, c'est de voir dans la doc que les exemples utilisent le "if __name__ == '__main__':"

    Quand à dire pourquoi ça marche comme ça...

    [Edit]: il y a une explication dans la doc. Extrait:

    For an explanation of why (on Windows) the if __name__ == '__main__' part is necessary, see Programming guidelines.
    Le reste de l'explication ici: "16.6.3.2. Windows" de la doc du module multiprocessing.

  4. #4
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Merci à tous de vos efforts !

    Je n'ai qu'un mot à dire : BEARK !
    C'est super moche ce truc qui dépend de global/pas global...
    Autant dire que ce module est inutilisable en cas réel sous Windaube !

    Tant pis, je me débrouillerais autrement...

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 754
    Par défaut
    Salut,

    Sous U**X, la bibliothèque peut s'appuyer sur "fork" pour créer les autres process. Sous Windows, fork n'existant pas, c'est "emulé" en recopiant les globals avec des "soucis" côté état des files descriptors.

    Ensuite, les mises à jours se font via IPC => sauf cas particulier le 'bootstrap' de l'application risque de ne pas être "portable" entre Windows et Linux.

    La bibliothèque concurrent.futures ajoute une couche d'abstraction "au dessus" de tout çà qui mérite le détour si le modèle de programmation parallèle est de type Worker's Queue.

    Ceci dit, la programmation parallèle avec les threads n'est pas simple, avec les process séparés c'est encore plus compliqué et donc à n'utiliser que si le problème à résoudre le "mérite" et non pour le fun.

    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. open avec comport
    Par Goldocrack dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/04/2009, 08h12
  2. Comportement d'incrémentation mystérieux
    Par helzix2 dans le forum Flash
    Réponses: 3
    Dernier message: 20/01/2009, 16h48
  3. Réponses: 16
    Dernier message: 30/01/2004, 11h05
  4. [Free Pascal] Comportement de Exec
    Par néo333 dans le forum Free Pascal
    Réponses: 3
    Dernier message: 01/11/2003, 17h46
  5. Réponses: 2
    Dernier message: 22/09/2003, 11h23

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