FAQ PythonConsultez toutes les FAQ

Nombre d'auteurs : 14, nombre de questions : 254, dernière mise à jour : 30 août 2014  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions posées sur le forum Python complétées par d'autres questions qui pouvaient nous sembler intéressantes de traiter. Toutefois il se peut que les réponses apportées contiennent des erreurs, imprécisions ... Vous pouvez dans ce cas contacter un des membres de la rédaction pour lui faire part de vos remarques.

L'équipe Python de Developpez.


SommaireThread (3)
précédent sommaire suivant
 

Les Thread en Python s'utilisent très facilement. Pour cela, il suffit de déclarer une instance par le constructeur threading.Thread( group=None, target=None, name=None, args=(), kwargs={}) où :

  • group doit rester à None, en attendant que la classe ThreadGroup soit implantée.
  • target est la fonction appelée par le Thread.
  • name est le nom du Thread.
  • args est un tuple d'arguments pour l'invocation de la fonction target
  • kwargs est un dictionnaire d'argumens pour l'invocation de la fonction target

il suffit ensuite pour exécuter le Thread d'appliquer la méthode start()

Code python :
1
2
3
4
5
6
7
8
9
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()

Mis à jour le 11 mai 2006 Guigui_

Nous allons ici simplement nous intéresser aux threads ne présentant pas d'accès concurrent à des ressources. L'objectif est donc simplement de tuer le thread lancé. Il existe pour cela plusieurs méthodes. Une première est d'appeler simplement la méthode MonThread._Thread__stop() qui termine l'instruction en cours et tue ensuite le thread.

Une deuxième méthode plus propre est de définir un paramètre Terminated initialisé à False et dand la méthode run de lancer une boucle infinie testant le booléen Terminated. Enfin, définissez une méthode stop qui met simplement le paramètre Terminated à True. Vous pouvez ajouter ou non un timer dans la méthode run pour que le thread ne monopolise pas toutes les ressources CPU. Vous retrouvez un tel exemple avec la classe Affiche. Pour arrêter le thread, on appelle simplement la méthode stop et une fois la boucle while entièrement parcourue, le thread se termine.

Code python :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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éthodemonevent.set() est appelée. La classe Affiche2 présente un exemple sur ce principe.

Code python :
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
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 = Affiche('Thread A') 
b = Affiche('Thread B') 
c = Affiche2('Thread C') 
  
a.start() 
b.start() 
c.start() 
time.sleep(6.5) 
a._Thread__stop() 
b.stop() 
c.stop()

Mis à jour le 16 octobre 2006 Guigui_ Wormus

A ma connaissance, il n'existe pas d'objet intrinsèque permettant de gérer un timer afin d'exécuter périodiquement un bout de code. Il est cependant possible avec la classe threading.Timer( interval, function, args=[], kwargs={}) de simuler ce comportement. Vous pouvez alors créer une fonction qui lancera un objet threading.Timer sur elle-même, ce qui aura pour effet de répéter périodiquement cette fonction. A la création de l'objet, vous devez fournir un flottant interval indiquant le temps d'attente (après le lancement de la méthode start()) avant l'exécution de la fonction function lancée avec les arguments args et kwargs.

Code python :
1
2
3
4
5
6
7
8
9
10
import threading 
import time 
  
def MyTimer(tempo = 1.0): 
    threading.Timer(tempo, MyTimer, [tempo]).start() 
    ## verification de la proprete du timer 
    print time.clock() 
    ## Reste du traitement 
  
MyTimer(2.0)
L'exemple précédent très simple ne permet pas de stopper et de relancer le Timer à votre guise.
Voici un exemple d'une classe gérant un Timer avec possibilité de l'arrêter et de le relancer. Ce Timer prend en paramètre la période du Timer (tempo), la fonction à appeler (target) et les arguments à passer à la fonction (une liste args et un dictionnaire kwargs). Vous pouvez alors lancer la fonction par la méthode start() et l'arrêter par la méthode stop()

Code python :
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
# -*- coding: cp1252 -*- 
import threading 
import time 
  
  
class MyTimer: 
    def __init__(self, tempo, target, args= [], kwargs={}): 
        self._target = target 
        self._args = args 
        self._kwargs = kwargs 
        self._tempo = tempo 
  
    def _run(self): 
        self._timer = threading.Timer(self._tempo, self._run) 
        self._timer.start() 
        self._target(*self._args, **self._kwargs) 
  
    def start(self): 
        self._timer = threading.Timer(self._tempo, self._run) 
        self._timer.start() 
  
    def stop(self): 
        self._timer.cancel() 
  
  
def affiche(unstr): 
    print unstr, time.clock() 
  
a = MyTimer(1.0, affiche, ["MyTimer"]) 
a.start() 
time.sleep(5.5) 
print u"Timer arrêté" 
a.stop() 
time.sleep(2.0) 
print u"Timer relancé" 
a.start()
Il existe d'autres implémentations de Timer, par exemple la bibliothèque wxPython fournit un objet wx.Timer

Mis à jour le 27 janvier 2007 Guigui_

Python Library Reference: Timer Object

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
 
 
 
Partenaires

PlanetHoster
Ikoula