IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

FAQ Python

FAQ PythonConsultez toutes les FAQ

Nombre d'auteurs : 11, nombre de questions : 188, dernière mise à jour : 14 juin 2021 

 
OuvrirSommaireThread

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()

 
Sélectionnez
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()
Créé le 11 mai 2006  par 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.

 
Sélectionnez
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.

 
Sélectionnez
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()
Créé le 16 octobre 2006  par 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.

 
Sélectionnez
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()

 
Sélectionnez
# -*- 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

Créé le 27 janvier 2007  par Guigui_

Lien : Python Library Reference: Timer Object

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 © 2005-2009 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.