python et les Threads¶
Comment utiliser simplement les Thread ?¶
import threading
def affiche(nb, nom = ''):
for i in range(nb): print nom, i
a = threading.Thread(None, affiche, None, (200,), {'nom':'thread a'})
b = threading.Thread(None, affiche, None, (200,), {'nom':'thread b'})
a.start()
b.start()
Comment arrêter définitivement un Thread ?¶
import threading
import time
class Affiche(threading.Thread):
def __init__(self, nom = ''):
threading.Thread.__init__(self)
self.nom = nom
self.Terminated = False
def run(self):
i = 0
while not self.Terminated:
print self.nom, i
i += 1
time.sleep(2.0)
print "le thread "+self.nom +" s'est termine proprement"
def stop(self):
self.Terminated = True
Le problème de la méthode précédente est donc le fait qu’il peut y avoir un laps de temps important entre le moment de la demande de l’arrêt du thread et celui où le thread est réèllement terminé dû à la durée du timer. En utilisant la classe Event, on peut ainsi accélérer l’arrêt du thread car la méthode monevent.wait(timeout) bloque le thread pendant la durée timeout où jusqu’au moment où la méthode monevent.set() est appelée. La classe Affiche2 présente un exemple sur ce principe.
class Affiche2(threading.Thread):
def __init__(self, nom = ''):
threading.Thread.__init__(self)
self.nom = nom
self._stopevent = threading.Event( )
def run(self):
i = 0
while not self._stopevent.isSet():
print self.nom, i
i += 1
self._stopevent.wait(2.0)
print "le thread "+self.nom +" s'est termine proprement"
def stop(self):
self._stopevent.set( )
a = Affiche2('Thread A')
b = Affiche2('Thread B')
c = Affiche2('Thread C')
a.start()
b.start()
c.start()
time.sleep(6.5)
a._Thread__stop()
b.stop()
c.stop()
Arrêter un thread par un control-C¶
rien de plus simple il suffit d’intercepter le KeyBoardInterrupted
import sys
#global
THREAD = None
class Affiche2(threading.Thread):
def __init__(self, nom = ''):
threading.Thread.__init__(self)
self.nom = nom
self._stopevent = threading.Event( )
def run(self):
i = 0
while not self._stopevent.isSet():
print self.nom, i
i += 1
self._stopevent.wait(2.0)
print "le thread "+self.nom +" s'est termine proprement"
def stop(self):
self._stopevent.set( )
def lanceprog():
THREAD = Affiche2('Thread C')
THREAD.start()
def exitprog():
THREAD.stop()
sys.exit(0)
try:
print 'Utilisez Control-C pour finir'
lanceprog()
except KeyboardInterrupt:
exitprog()