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

PyQt Python Discussion :

[QThread] Lancer plusieurs threads en parallele


Sujet :

PyQt Python

  1. #1
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut [QThread] Lancer plusieurs threads en parallele
    Bonjour,

    je débute avec la notion de thread et je ne parviens pas à obtenir le comportement que je veux dans mon appli PyQt.
    J'ai une liste de simulations numériques à lancer, et je voudrais les lancer simultanément.
    Une "simulation" est représentée dans mon programme par un nom de fichier. Je démarre la simulation en utilisant os.system() afin d'exécuter ce fichier.
    Lorsque plusieurs fichiers sont exécutés en même temps, le simulateur se charge tout seul de répartir les simulations sur les différents CPU de la machine.
    Voici mon code (version simplifiée):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def lancerSimusParallele(self, listeSimus):
        '''
        SLOT d un bouton "Demarrer" de l IHM 
        - listeSimus: [list de str] liste des fichiers a executer
        '''
        for i in range(listeSimus):
            thread = ThreadSimu(listeSimus[i], i)
            thread.start()
    Avec ci-dessous le code de ma classe "ThreadSimu":
    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
    31
    32
    class ThreadSimu(QtCore.QThread):
        '''
        QThread pour le lancement d une simulation
        '''
        def __init__(self, simu, numSimu):
            '''
            Constructeur de la classe ThreadSimu
            - simu: [str] fichier correspondant a la simulation a lancer
            - numSimu: [int] numero de la simulation
            '''
            QtCore.QThread.__init__(self)
            self.simu = simu
            self.numSimu = numSimu
     
        def start(self):
            '''
            Demarrage de la simulation
            '''
            print "DEMARRAGE DE LA SIMULATION%d"%self.numSimu
            # precalculs avant l execution du fichier
            [...]
            # Execution du fichier
            status = os.system("sh %s &" % self.simu)
            self.run()
     
        def run(self):
            '''
            Suivi du deroulement de la simulation
            '''
            time.sleep(3)   # En realite, lecture de fichiers et affichage de l'avancement sur l'IHM grace a des signaux
     
            print "SIMULATION %d TERMINEE"%self.numSimu
    (Précision je suis sous Linux).
    Voici le comportement que je souhaite avoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DEMARRAGE DE LA SIMULATION 1
    DEMARRAGE DE LA SIMULATION 2
    DEMARRAGE DE LA SIMULATION 3
    [...] 3 secondes s ecoulent...
    SIMULATION 1 TERMINEE
    SIMULATION 2 TERMINEE
    SIMULATION 3 TERMINEE
    Voici le comportement que j'ai avec le code ci-dessus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    DEMARRAGE DE LA SIMULATION 1
    [...] 3 secondes s ecoulent...
    SIMULATION 1 TERMINEE
    DEMARRAGE DE LA SIMULATION 2
    [...] 3 secondes s ecoulent...
    SIMULATION 2 TERMINEE
    DEMARRAGE DE LA SIMULATION 3
    [...] 3 secondes s ecoulent...
    SIMULATION 3 TERMINEE
    Le lancement des Threads en parallele ne fonctionne donc pas du tout, mais je ne comprends pas ce qui ne va pas dans mon code?
    Merci d'avance pour votre aide!

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Il faut mettre le code à exécuter dans la méthode "run" pas dans "start".
    Comme vos QThread se résument a faire des appels os.system, vous pourriez utiliser QProcess directement.

    Il y pleins de discussion sur ces sujets dans le forum PyQt/PySide: je vous laisse rechercher un peu.

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

  3. #3
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Bonjour,

    D'accord je peux mettre la ligne os.system() dans run() au lieu de start(), mais j'ai tout de même besoin de la fonction start pour faire tous mes précalculs, et dans ma fonction run je ne fais pas qu'executer le fichier, je fais ensuite un suivi du déroulement de la simulation jusqu'à ce qu'elle soit terminée (je n'ai pas mis tout mon code dans mon exemple).
    C'est pour cela que j'ai utilisé QThread, cela me permet d'utiliser des signaux liés à des SLOTS de mon IHM et ainsi mettre à jour une sortie console et une barre de progression.

    J'avais fait une recherche pour trouver un exemple similaire à mon cas, et a priori le fait d'appeler les méthodes start() de chaque thread devrait les lancer en même temps non?
    Dans la FAQ il y a cet exemple:
    utilisation Thread
    il lance bien a.start et b.start à suivre (c'est Thread et non QThread, mais cela doit fonctionner de la même façon non?)

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    [I]
    Citation Envoyé par mokochan Voir le message
    J'avais fait une recherche pour trouver un exemple similaire à mon cas, et a priori le fait d'appeler les méthodes start() de chaque thread devrait les lancer en même temps non?
    Il n'est pas interdit de surcharger "start" (ou toute autre méthode héritée).
    Mais si vous oubliez d'appeler le "start" parent, le démarrage du thread ne sera pas fait.

    Citation Envoyé par mokochan Voir le message
    D'accord je peux mettre la ligne os.system() dans run() au lieu de start(), mais j'ai tout de même besoin de la fonction start pour faire tous mes précalculs, et dans ma fonction run je ne fais pas qu'executer le fichier, je fais ensuite un suivi du déroulement de la simulation jusqu'à ce qu'elle soit terminée (je n'ai pas mis tout mon code dans mon exemple).
    C'est pour cela que j'ai utilisé QThread, cela me permet d'utiliser des signaux liés à des SLOTS de mon IHM et ainsi mettre à jour une sortie console et une barre de progression.
    Je ne vois pas pourquoi vous ne pourriez pas faire cela avec QProcess. J'avais pondu un exemple ici. Il montre un QProcess qui met à jour un widget Text via un slot.
    La propriété du QProcess ou du QThread dont on a besoin est de dérouler le GUI et des taches en parallèles. La différence est que QProcess permet de lancer une commande externe, alors qu'avec QThread on reste "dans" la même application, le même espace d'adressage,...

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

  5. #5
    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,

    Voilà un petit code de test à lancer en console qui montre comment faire fonctionner les QThreads:

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Python 3.4
     
    import sys, os
    from time import sleep
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Monthread(QtCore.QThread):
     
        #========================================================================
        def __init__(self, num, parent=None):
            super(Monthread, self).__init__(parent)
     
            self.encore = True
            self.num = num
     
        #========================================================================
        def run(self):
            """partie qui s'exécute en tâche de fond"""
     
            print("début du thread ", self.num) 
     
            while self.encore:
                print(self.num)
                sleep(0.2)
     
            print("fin du thread ", self.num)       
     
        #========================================================================
        def stop(self):
            """pour arrêter avant la fin normale d'exécution du thread"""
            self.encore = False
     
    #############################################################################
     
    app = QtCore.QCoreApplication(sys.argv)
     
    thr = []
     
    for i in range(0, 5):
        thr.append(Monthread(i))
     
    for i in range(0, 5):
        thr[i].start()
     
    sleep(1)
     
    for i in range(0, 5):
        thr[i].stop()
     
    sleep(1)
    Ce qui donne quelque chose comme:

    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
    31
    32
    33
    34
    35
    36
    37
    38
    début du thread  0
    0
    début du thread  1
    1
    début du thread  2
    2
    début du thread  3
    début du thread  4
    3
    4
    0
    4
    1
    2
    3
    1
    4
    0
    3
    2
    1
    4
    0
    3
    2
    0
    4
    1
    2
    3
    0
    4
    1
    fin du thread  2
    fin du thread  3
    fin du thread  4
    fin du thread  1
    fin du thread  0
    En utilisant les processus au lieu des threads, le module Python multiprocessing est intéressant car il fonctionne sur le même modèle que les threads (threading ou QThread).
    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

  6. #6
    Membre averti
    Femme Profil pro
    Ingénieur informatique scientifique
    Inscrit en
    Mai 2010
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur informatique scientifique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2010
    Messages : 313
    Points : 301
    Points
    301
    Par défaut
    Merci pour vos réponses j'y vois plus clair.

    Citation Envoyé par wiztricks
    Mais si vous oubliez d'appeler le "start" parent, le démarrage du thread ne sera pas fait.
    En effet je n'y avait pas pensé. Finalement j'ai préféré modifier mon code pour faire mes précalculs à un autre endroit, je ne surcharge plus "start".
    Si j'ai bien compris c'est à cause de ça que mon code ne fonctionnait pas.

    Merci pour l'exemple Tyrtamos ça fonctionne très bien.

    Problème résolu!

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

Discussions similaires

  1. lancer plusieurs threads a la fois
    Par j2ee60 dans le forum Général Java
    Réponses: 0
    Dernier message: 29/04/2011, 21h20
  2. [PHP 5.2] Lancer plusieurs threads en ligne de commande
    Par max-mag dans le forum Langage
    Réponses: 1
    Dernier message: 24/02/2010, 08h58
  3. Lancer plusieurs Thread exactement en même temps
    Par remax_ren dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 21/04/2009, 11h25
  4. Réponses: 2
    Dernier message: 16/02/2009, 15h21
  5. Lancer plusieur thread sur la meme fonction
    Par daviddu54 dans le forum Windows Forms
    Réponses: 8
    Dernier message: 17/01/2008, 11h34

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