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 :

Probleme avec les threads


Sujet :

Python

  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2008
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2008
    Messages : 327
    Points : 257
    Points
    257
    Par défaut Probleme avec les threads
    Bonjour a tous,

    Je ne pense pas être le seul a avoir des problèmes avec les threads mais je ne pense pas que se problème est déjà été posé (en tout cas je les pas vue ^^).

    Voila c'est très simple, je crée un lecteur de musique (mais sa n'a rien a voir avec les fonctions de musiques), je tiens a signaler que je gère une interface graphique sous pygtk (glade) et donc j'utilise les threads pour lire ma musique et me permettre de continuer a pouvoir utiliser mon interface (j'ai posté sa ici car je ne pense pas que le probleme vienne de l'interface).

    En gros lorsque je clic sur play sa lance le thread (voir script ci-dessous) sauf que quand je le lance, sa fait rien, ou en tout cas jusqu'a ce que je ferme mon interface ou la le thread prend le relai (mais dans se cas le thread sert a rien car il gere pas ma fonction en paralelle).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class programme:
     
        def lancer(self):
             Player(fichier).start()
     
     
    class Player(threading.Thread, programme):
     
        def __init__(self, nom):
            self.nom = nom
            threading.Thread.__init__(self)
     
        def run(self):
            ...lire la chanson
    Voila comment je lance mon thread (j'ai pas tout mit bien sur ^^).

    J'ai trouvé une solution temporaire mais vraiment pas pratique, voici mon new script (juste quelques lignes en plus)

    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
    class programme:
     
        def lancer(self):
             Player(fichier).start()
     
     
    class Player(threading.Thread, programme):
     
        def __init__(self, nom):
            self.nom = nom
            threading.Thread.__init__(self)
            gobject.idle_add(self.rafraichissement)
     
        def rafraichissement(self):
            return True
     
        def run(self):
            ...lire la chanson
    Ici pas grand chose diffère mais sa marche, pourquoi ? Alors j'ai utilisé les modules gobject pour dire a mon programme, lorsque ce dernier est inactif (quand je fais rien) tu raffraichis alors rafraichir pour moi c'ets juste le défiger sa force ma classe a fonctionner et la ma fonction run marche niquel.

    Mais alors ou est mon probleme si j'ai trouvé une petite solution ? Mais la le probleme devient énorme lol, c'est que dans se cas de figure la, le programme tourne 24/24 7/7 et meme jour ferrier lol, non mais se que je veux dire c'est que en general les programmes utilises les ressources de l'ordi temporairement mais la sa pompe tout, direct je monte à 50 k de mémoire utilisé, mon processeur est à 50 % tout le temps que le programme est lancé, c'est un vrai gouffre cette solution. Impossible de lancer d'autres programmes un peu lourds sans tout faire rammer.

    Je me demandais donc (je demande mais je me dis que c'est obligé qu'une solution existe car je n'imagine pas que tous les programmes python qui utilises une interfaces graphique et des thread est recourd a sa), s'il n'y avait pas un moyen pour dire au thread de se lancer et de pas se figer ou attendre la fin du programme ?

    Merci a tous d'avance et bonne continuation

  2. #2
    Membre régulier

    Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2009
    Messages : 70
    Points : 71
    Points
    71
    Par défaut
    je sais pas si sa va t'aider mais moi j'écriré :

    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
    class programme:
     
        def lancer(self):
             t1=Player()
             t1.start()
     
     
    class Player(threading.Thread, programme):
     
        def __init__(self, nom):
            self.nom = nom
            threading.Thread.__init__(self)
     
        def run(self):
            ...lire la chanson
    aprés je sais pas si sa va t'aider

    Edité par Guigui: merci de penser aux balises [CODE]

  3. #3
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Citation Envoyé par silver093 Voir le message
    Ici pas grand chose diffère mais sa marche, pourquoi ?
    Lorsque gtk tourne, il a une liste qui contient, dans l'ordre, les tâches à effectuer. Ca comprend les clicks de souris, les refresh d'écran etc. Si tu mets une thread en parallèle sans passer par gobject.idle_add, ce qu'on appelle le GIL (Global Interpreter Lock) de python crée un deadlock (il y a conflit de synchronisation).
    Je te conseille également d'appeler la fonction gtk.gdk.threads_init() avant de commencer à travailler avec la GUI. C'est normalement nécéssaire pour le bon fonctionnement des threads avec gtk.

    mon processeur est à 50 % tout le temps que le programme est lancé, c'est un vrai gouffre cette solution. Impossible de lancer d'autres programmes un peu lourds sans tout faire rammer.
    C'est peut-être du au fait que tu n'appelles pas la fonction que j'ai mise plus haut. C'est peu probable, mais essaye ça en premier.
    Sinon, vois du côté du lecteur audio, le souci est peut-être là.

    Et si ce n'est tjs pas ça, donne plus de ton code, on pourra sans doute te donner plus d'infos.

    Edit: heu... je ne comprends pas à quoi te sert la méthode rafraichissement... elle ne sera exécutée qu'une fois.
    Tu devrais plutot donner à gobject.idle_add la fonction que tu veux démarrer. Dans ce cas ci, la thread de lecture.
    Le souci vient surement de là. L'appel à rafraichissement rajoute un délai, ce qui laisse le temps à ton thread de se lancer différemment que dans ton premier code. Le tout bloque bien sur le GIL, et c'est parti pour la folie :p

  4. #4
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2008
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2008
    Messages : 327
    Points : 257
    Points
    257
    Par défaut
    Bon ba déja merci a vous deux, en particulier a cette derniere reponse, en effet, la fonction que tu m'as donné marche un peu mieu ^^ enfin en tout cas, je n'ai pas besoin d'appeller la fonction raffraichissement pour que ma musique se joue, en revanche meme si sa marche, sa marche pas longtemps. Je ne sais plus si je l'ai dit mais mon thread au dela de jouer la musique, modifie l'interface graphique et quand je lance le thread au bout de quelque secondes, python arrete de fonctionner.

    Alors comme je viens de découvrir qu'il fallait faire appel a un autre type de thread pour les GUI tel que Pygtk que ceux du python sous console, je ne voix pas encore d'ou peut venir l'erreur ^^.

    En tout cas merci, et si jamais tu auras d'autre idée brillante je suis a ta disposition et a celle des autres

    Voila mon new code :

    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
    class programme:
     
        def lancer(self):
             Player(fichier).start()
     
     
    class Player(threading.Thread, programme):
     
        def __init__(self, nom):
            self.nom = nom
            threading.Thread.__init__(self)
     
        def run(self):
            ...lire la chanson
     
    gtk.gdk.threads_init()
    app = monprogramme()
    gtk.main()

  5. #5
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Non, je n'ai pas dit qu'il ne fallait pas utiliser idle_add Ici de nouveau, tu lances une thread hors gtk, et le GIL se bloque.
    Ceci devrait fonctionner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class programme:
        def lancer(self):
             gobject.idle_add(Player(fichier).start)
     
    gtk.gdk.threads_init()
    app = monprogramme()
    gtk.main()
    Au passage, par convention et sécurité, je te conseille d'appeler le __init__ de tes superclasses en tout premier dans ton __init__.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Player(Thread):
        def __init__(self):
            Thread.__init__(self)
             # Suite

Discussions similaires

  1. probleme avec les threads et class
    Par cosmoff dans le forum Général Python
    Réponses: 1
    Dernier message: 25/05/2015, 14h32
  2. probleme avec les thread
    Par ashurah dans le forum Concurrence et multi-thread
    Réponses: 15
    Dernier message: 26/03/2010, 14h05
  3. Probleme avec les Threads
    Par ouxss dans le forum C++
    Réponses: 2
    Dernier message: 05/01/2010, 10h27
  4. Probleme avec les thread
    Par jonny dans le forum MFC
    Réponses: 11
    Dernier message: 01/06/2006, 17h37
  5. Probleme avec les threads
    Par Orahn dans le forum MFC
    Réponses: 5
    Dernier message: 04/11/2005, 10h14

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