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 :

finir correctement un thread


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Points : 9
    Points
    9
    Par défaut finir correctement un thread
    bonjour,

    J'ai un programme dans lequel j'ai fait un thread consacré à la gestion des fonctions midi input.
    Pour le midi j'utilise le module pypm (pyportmidi).
    Mon code est le suivant
    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
    27
    28
    29
    30
    import pypm
    import array
    import time
    from threading import Thread
     
    class Midi(Thread):
        def __init__(self,midion):
                Thread.__init__(self)
                pypm.Initialize()
                self.midion = midion
                self.MidiIn = None
                try :
                    self.MidiIn = pypm.Input(1)
                except:
                    self.exit()
     
     
        def run(self):
            while not self.MidiIn.Poll(): time.sleep(.01)
            while self.midion:
                try:
                    self.MidiData = self.MidiIn.Read(1) # read only 1 message at a time
                    print self.MidiData[0][0][1]," ",self.MidiData[0][0][2], self.MidiData[0][0][3]
     
                except:
                    pass   
     
    if __name__ == '__main__':
        m = Midi(1)
        m.start()
    Mon problème est que lorsque je lance ce code seul dans une console par exemple, il s'éxécute correctement, mais lorsque je veux fermer la console la console ne se ferme pas et m'affiche :
    pn_winmm_term called
    begin closing open devices...
    et la fermeture des interfaces ouvertes ne se fait pas et la fenêtre console finit par me dire que "ce programme n'a pas pu se terminer normalement, voulez vous le terminer maintenant, ..."
    Bref une sortie assez désastreuse.

    D'autre part, lorsque j'utilise ce code dans un programme, mon programme s'arrête à la ligne M.start() et ne va pas plus loin. Comme si il attendait quelque chose pour continuer.

    Une idée ?

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En principe, un programme qu'on veut arrêter attend que ses threads se terminent. S'ils ne se sont pas terminé normalement, il ne reste plus qu'à faire un arrêt "sauvage".

    Pour éviter cela, et dans la mesure où on peut arrêter les threads à n'importe quel moment sans conséquence, il suffit de les déclarer "démon":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
    m = Midi(1)
    m.setDaemon(True)
    m.start()
    ...
    Une autre solution plus élégante est d'intégrer une condition d'arrêt dans la méthode run du thread, et de déclencher l'arrêt sur demande:

    - initialisation du drapeau dans l'__init__: self.encore = True

    - condition d'arrêt dans la boucle de travail du run: while self.midion and self.encore:

    - et déclenchement de l'arrêt avec une méthode supplémentaire pour le thread du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    def stopthread(self):
        self.encore = False
    Ainsi, un simple appel m.stopthread() arrête le thread

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Points : 9
    Points
    9
    Par défaut
    merci tyrtamos,

    Déclarer l'instance comme démon n'arrange rien car le module pypm attend pypm.Terminate() pour sortir coorectement. Sinon, dans tous les cas (démon ou pas) lors de la fermeture il bloque sur la fermeture des interfaces ouvertes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    begin closing open devices ...
    Donc il faut effectivement appelé cette méthode dans une fonction stop.

    Je me demandais si il n'existe pas une méthode dans python qui permet d'appelé des fonctions ou méthodes lorsqu'on appelle sys.exit et avant que sys.exit ne s'exécute.
    Faut il re définir sys.exit dans la classe qui appelle cette fonction ?

Discussions similaires

  1. Synchroniser correctement deux threads
    Par supcomingenieur dans le forum Général Java
    Réponses: 13
    Dernier message: 16/04/2013, 15h46
  2. [QtCore] Utiliser correctement les threads
    Par manuaarts dans le forum PyQt
    Réponses: 1
    Dernier message: 01/08/2012, 12h14
  3. Réponses: 0
    Dernier message: 29/12/2010, 00h06
  4. problème thread ne s'exécute pas correctement
    Par oumay dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 04/03/2010, 12h15
  5. Cela vous semble-t-il correct? (gestion d'un Thread)
    Par Micke7 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 19/11/2008, 15h43

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