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 :

Queue, Thread et synchronisation


Sujet :

Python

  1. #1
    Membre émérite
    Avatar de panda31
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2003
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2003
    Messages : 670
    Par défaut Queue, Thread et synchronisation
    Bonjour à tous,

    J'ai un souci de conception et/ou de langage sur les threads.
    Pour situer le topo, je fais un lanceur de tâches avec une GUI en Tkinter. Chaque tâche est lancée dans un thread.
    Le problème est que je veux que le thread n+1 ne se lance pas avant la fin d'exécution du thread n.

    J'ai lu quelques doc et la doc officielle du module Queue qui semble la clé du problème mais je pige pas trop comment s'imbrique le tout.

    Pouvez-vous m'aider svp ?

    Merci d'avance !
    Michaël Mary
    Consultant PLM dans une société de conseil toulousaine
    Auditeur CNAM-IPST depuis septembre 2008
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    John F. Woods
    mon cv et mon domaine et mon blog
    Aucune question technique par MP, svp

  2. #2
    Membre émérite
    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
    Par défaut
    Salut

    C'est un peu trop flou pour pouvoir t'aider efficacement.
    Peux-tu préparer à l'avance tous les threads avant de lancer le premier ou vas tu en ajouter au fur et à mesure ?
    Si tu en rajoutes, quel thread les rajoute ? le main, ou un des threads lancés ?

    De ce que je vois, une solution serait d'avoir un thread qui se charge de lancer les autres à tour de rôle, à l'aide de wait et autres.
    Ces threads seraients stockés dans une simple liste.
    Tu peux utiliser une queue à la place si tu as besoin d'empêcher les accès concurrents à cette liste.

    Ca ressemblerait un peu à ceci (non testé):
    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
    from threading import Thread
    from queue import Queue
     
    class ThreadManager(Thread):
        def __init__(self):
            Thread.__init__(self)
            self.__queue = Queue(0)
     
        def enqueueThread(self, thread):
            self.__queue.put(thread)
     
        def run(self):
            while 1:
                nextThread = self.__queue.get(True)
                nextThread.start()
                nextThread.wait()
     
    # Et dans ton code sensé lancer les tâches
    threadManager = ThreadManager()
    threadManager.start()
     
    # Ajout d'une tâche
    threadManager.enqueueThread(myThread)
    Je pense qu'avec quelques détails de plus on pourrait sans doute te donner une meilleure réponse

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 139
    Par défaut
    Sinon tu as la méthode .join() dans threading qui permet d'attendre la fin de l'execution du thread associé pour continuer

    Par exemlpe tu a un thread appelé "MyToto" qui tourne

    si tu utilise MyToto.join(),ton prog restera bloqué à cette ligne la jusqu'à la fin de l'éxécution du ton thread

  4. #4
    Membre émérite
    Avatar de panda31
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2003
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2003
    Messages : 670
    Par défaut
    Alors, pour préciser davantage :
    - Je crée mes thread et je les stocke dans une liste
    - Je veux ensuite les lancer les uns après les autres en précisant que le 2nd ne démarre qu'après la fin du premier, etc...

    Est-ce plus clair ?
    Michaël Mary
    Consultant PLM dans une société de conseil toulousaine
    Auditeur CNAM-IPST depuis septembre 2008
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    John F. Woods
    mon cv et mon domaine et mon blog
    Aucune question technique par MP, svp

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 139
    Par défaut
    je confirme...méthode join()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    liste = [thread1,thread2,...,threadn]
     
    for i in len(liste):
          liste[i].start()
          liste[i].join()

  6. #6
    Membre émérite
    Avatar de panda31
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2003
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2003
    Messages : 670
    Par défaut
    Si tu fais cela, tu prends le risques de freezer l'ihm non ?
    Michaël Mary
    Consultant PLM dans une société de conseil toulousaine
    Auditeur CNAM-IPST depuis septembre 2008
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    John F. Woods
    mon cv et mon domaine et mon blog
    Aucune question technique par MP, svp

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 139
    Par défaut
    Bah je sais pas, je me base sur le cahier des charges que tu as défini:

    Alors, pour préciser davantage :
    - Je crée mes thread et je les stocke dans une liste
    - Je veux ensuite les lancer les uns après les autres en précisant que le 2nd ne démarre qu'après la fin du premier, etc...

    Est-ce plus clair ?
    C'est exactement ce que réalise la p'tite boucle for...

  8. #8
    Membre émérite
    Avatar de panda31
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2003
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2003
    Messages : 670
    Par défaut
    C'est pas faux. Bon alors :
    - J'ai une ihm en tkinter dans laquelle j'ai une liste d'actions à lancer (je peux cocher / décocher ...)
    - J'ai un bouton Run qui, lorsque je click, lance toutes les actions sélectionnées.

    Je veux garder l'IHM réactive pendant l'exécution des tâches (certaines peuvent être longues). Chaque tâche est lancée dans un thread. Le point noir pour moi est de permettre l'exécution de la tache N+1 seulement après la fin de la tâche N.
    Michaël Mary
    Consultant PLM dans une société de conseil toulousaine
    Auditeur CNAM-IPST depuis septembre 2008
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    John F. Woods
    mon cv et mon domaine et mon blog
    Aucune question technique par MP, svp

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 139
    Par défaut
    Et bien je dirai...PAREIL, sauf que tu ne met pas le thread de l'IHM dans ta liste, mais uniquement ceux qui doivent être imbriqué...
    Et tu met tout ca encore dans un thread ce qui donne:

    1 thread qui gere l'IHM

    1 thread qui gere la liste et qui se lance lorsqu'on clique sur le bouton "RUN"

    Et tout ce p'tit monde qui fonctionne tous ensemble

    Et voili
    (enfin c'est comme ca que je ferai...mais y'as p'tet des trucs plus sioux!)

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 742
    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 742
    Par défaut
    Citation Envoyé par panda31 Voir le message
    C'est pas faux. Bon alors :
    - J'ai une ihm en tkinter dans laquelle j'ai une liste d'actions à lancer (je peux cocher / décocher ...)
    - J'ai un bouton Run qui, lorsque je click, lance toutes les actions sélectionnées.

    Je veux garder l'IHM réactive pendant l'exécution des tâches (certaines peuvent être longues). Chaque tâche est lancée dans un thread. Le point noir pour moi est de permettre l'exécution de la tache N+1 seulement après la fin de la tâche N.
    Pourquoi ne pas parler de commandes à lancer dans leur ordre de soumission?
    Dans ce cas, un seul thread suffirait pour les traiter l'une après l'autre (en les récupérant dans la Queue.Queue).

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

  11. #11
    Membre émérite
    Avatar de panda31
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Juin 2003
    Messages
    670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2003
    Messages : 670
    Par défaut
    Tu peux développer stp ?
    Michaël Mary
    Consultant PLM dans une société de conseil toulousaine
    Auditeur CNAM-IPST depuis septembre 2008
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live."
    John F. Woods
    mon cv et mon domaine et mon blog
    Aucune question technique par MP, svp

  12. #12
    Membre émérite
    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
    Par défaut
    Citation Envoyé par panda31 Voir le message
    Si tu fais cela, tu prends le risques de freezer l'ihm non ?
    Pas avec Tkinter il me semble. Si mes souvenirs sont justes, les gui tk sont gérées par un processus externe.

  13. #13
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 742
    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 742
    Par défaut
    Citation Envoyé par panda31 Voir le message
    Tu peux développer stp ?
    J'ai construit cela à partir d'un code beaucoup plus compliqué pour te montrer l'idée (il va te falloir réfléchir un peu pour que ça marche ;-(
    Ca fait quoi?
    1. On crée une queue et une thread encapsulée dans la class CommandQ...
    2. Démarrage de la thread: cmq.start ou empilage des commandes via cmq.submit_command.
    3. _runLoop dépile commande et arguments et les exécute...

    Comme nous n'avons qu'un thread, on ne peut faire N+1 qu'après N tout en pouvant faire autre chose dans le contexte 'parent'.

    Subtilités....
    • faut-il que le thread soit ou pas un daemon?
    • faut-il avoir un cmq permanent ou en créer un dès qu'on a un paquet de commandes?
    • est-il nécessaire d'attendre la fin de.... comment?

    C'est ce que j'appellerais des 'finitions'.
    - W
    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
    import threading, Queue
     
    class CommandQ(object):
        def __init__(self):
            self._commands = Queue.Queue()
            self._thread   = threading.Thread(target=self._runLoop)
            self._done_event = threading.Event()
     
        def submit_command(self, method, *args, **kwds):
            self._commands.put ( (method, args, kwds) )
     
        def _runLoop(self):
            while True:
                if self._done_event.is_set():
                    break
                try:
                    method, args, kwds = self._commands.get(block=False)
                except Queue.Empty():
                    time.sleep(0.05)
                else:
                    try:
                        result = method(*args, **kwds)
                    except Exception, exc:
                        pass #
     
        def start(self):
            time.sleep(0)
            self._thread.start()
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Par défaut
    Et thread.Event() ne conviendrait pas ?

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

Discussions similaires

  1. Threads et synchronisation
    Par divxdede dans le forum Concurrence et multi-thread
    Réponses: 6
    Dernier message: 25/09/2007, 14h26
  2. Thread et synchronisation
    Par Invité dans le forum Concurrence et multi-thread
    Réponses: 8
    Dernier message: 15/03/2007, 11h17
  3. créer Thread et synchronisation C et VB
    Par storm_2000 dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 20/01/2007, 12h49
  4. [THREAD] Problème synchronisation
    Par goddet dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 25/10/2006, 09h16
  5. [JNI] Class Thread et Synchronisation
    Par SteelBox dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 22/02/2006, 23h40

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