Warning: Undefined array key "DOKU_PREFS" in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/common.php on line 2082
thread_ordre [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


thread_ordre

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
Dernière révision Les deux révisions suivantes
thread_ordre [2008/05/06 08:23]
tyrtamos
thread_ordre [2008/05/06 09:14]
tyrtamos
Ligne 13: Ligne 13:
 Le principe est simple: Le principe est simple:
  
-  * on créé une variable globale "statut" initialisé à 1, et chaque thread pourra la lire et la modifier+  * on créé une variable globale "statut" initialisé à 0, et chaque thread pourra la lire et la modifier
  
   * on créé le verrou "vstatut" (threading.Lock()) qui ne permettra l'accès à la variable "statut" par les threads qu'un à la fois.   * on créé le verrou "vstatut" (threading.Lock()) qui ne permettra l'accès à la variable "statut" par les threads qu'un à la fois.
Ligne 81: Ligne 81:
  
 # création de la variable globale partagée statut et de son verrou # création de la variable globale partagée statut et de son verrou
-statut = 1+statut = 0
 vstatut = threading.Lock() vstatut = threading.Lock()
  
Ligne 107: Ligne 107:
  
 # arrêt de tous les threads # arrêt de tous les threads
-vprint.acquire() 
 for i in xrange(0,nbacteurs): for i in xrange(0,nbacteurs):
     acteurs[i].stop()     acteurs[i].stop()
-    print "stopper le thread " + acteurs[i].getName() +    
-print "fini" +
-vprint.release() +
 # attente pour terminer que tous les threads soient arrêtés # attente pour terminer que tous les threads soient arrêtés
 for i in xrange(0,nbacteurs): for i in xrange(0,nbacteurs):
     acteurs[i].join()     acteurs[i].join()
 +    vprint.acquire()
 +    print "fin du thread " + acteurs[i].getName()
 +    vprint.release()
 +    
 +print "fini"
 </code> </code>
  
Ligne 123: Ligne 124:
 <code> <code>
 debut debut
 +action faite par A0
 action faite par A1 action faite par A1
 action faite par A2 action faite par A2
Ligne 160: Ligne 162:
 stopper le thread A9 stopper le thread A9
 fini fini
 +</code>
 +
 +===== Solution avec une condition (threading.Condition()) =====
 +
 +C'est la même chose qu'un verrou, et cela affiche la même chose, à part qu'on peut espérer que l'attente de la condition (.wait()) consomme moins de ressources machine que la boucle while d'attente du bon statut.
 +
 +<code python>
 +#!/usr/bin/python
 +# -*- coding: utf-8 -*-
 +
 +import threading
 +import time
 +
 +###############################################################################
 +class Acteur(threading.Thread):
 + 
 +    def __init__(self, nom, st1, st2):
 +        threading.Thread.__init__(self)
 +        self.setName(nom)
 +        self.st1 = st1  # = statut qui déclenche l'action
 +        self.st2 = st2  # = statut pour passer la main au thread suivant
 +        self.marche = True  # drapeau pour stopper le thread à la demande
 + 
 +    def run(self):
 +        global statut, cstatut, vprint
 +
 +        while self.marche:
 +            # attente du bon statut avant l'action prévue:
 +            cstatut.acquire()
 +            if statut!=self.st1:
 +                cstatut.wait()
 +            cstatut.release()
 +            time.sleep(0.1)
 +
 +            # action prévue par le thread
 +            if self.marche:
 +                vprint.acquire()
 +                print "action faite par " + self.getName()
 +                vprint.release()
 +
 +            # fin de l'action: le thread passe la main au suivant
 +            cstatut.acquire()
 +            #print self.getName(), statut 
 +            statut=self.st2
 +            cstatut.notifyAll()
 +            cstatut.release()
 +
 +    def stop(self):
 +        self.marche = False
 +
 +###############################################################################
 +
 +print "debut"
 +
 +# création de la variable globale partagée statut et de son verrou
 +statut = 0
 +cstatut = threading.Condition()
 +
 +# création d'un verrou pour l'impression par les thread
 +vprint = threading.Lock()
 +
 +# creation d'une liste de thread
 +nbacteurs = 10
 +acteurs = []
 +for i in xrange(0,nbacteurs):
 +    if i==(nbacteurs-1):
 +        k = 0
 +    else:
 +        k = i+1
 +    a = Acteur("A%d" % i, i, k)
 +    a.setDaemon(True)
 +    acteurs.append(a)
 +
 +# lancement de tous les threads
 +for i in xrange(0,nbacteurs):
 +    acteurs[i].start()
 +
 +# attente 5 secondes
 +time.sleep(5)
 +
 +# arrêt de tous les threads
 +for i in xrange(0,nbacteurs):
 +    acteurs[i].stop()
 +    
 +# attente pour terminer que tous les threads soient arrêtés
 +for i in xrange(0,nbacteurs):
 +    acteurs[i].join()
 +    vprint.acquire()
 +    print "fin du thread " + acteurs[i].getName()
 +    vprint.release()
 +    
 +print "fini"
 </code> </code>
thread_ordre.txt · Dernière modification: 2008/05/08 20:25 de tyrtamos