OVH Cloud OVH Cloud

besoin d'aide pour le module threading

2 réponses
Avatar
chahnaz.ourzikene
Bonjousoir,

Voilà, je voulais faire un peu joujou avec les threads, comme j'en avais
besoin pour une autre application, alors je me suis dis faisons un petit
teste sur un petit exemple pour bien voir si j'arrive à obtenir l'effet
désirée sur l'application finale.

J'ai besoin d'écrire un thread (controlleur) qui va inspecter l'état (disons
une variable d'état par exemple, qui dans cette exemple est un simple
compteur) d'un objet (sujet) qu'il surveil en permanence , et qui va lancer
une action (dans mon exemple, faire un print et retourner) quand la variable
d'état de l'objet surveillé vérifie une certaine condition (disons qu'elle
passe à dix ou supérieur dans mon exemple tout bête).

Le thread controlleur va donc lancer, dans une boucle while infinie, une
suite de requêtes de services sur l'objet étudié en lui demandant quelle est
la valeur de la variable d'état par m'intermediaire de la methode 'count' de
l'objet sujet. Le sujet fournit le service et lui donne la valeur de la
variable d'état. Le thread d'execution teste ensuite si cette valeur est
supérieur ou égale à dix. Si le teste est vrai, il déclanche une action
(fait un print) et retourn, sinon il réiter.

Alors comme je m'y connais pas trop, voici le code que j'ai écrit :

<code>
from threading import *

####################################

class Subject(object):


def __init__(self) :

self.counter = 0

t = Timer(0.00001,self.doIteratingStuff)

t.start()


def incrementCounter(self,n=1) :

self.counter = self.counter + n

def doIteratingStuff(self) :

for i in range(10) :

self.incrementCounter(4)

print "the counter is now", self.counter


def count(self):

return self.counter

####################################

class Controller(object):

def __init__(self, objectToControl) :

self.controlled = objectToControl

self.th = Thread(target = self.stopCounting)

def start(self):

self.th.start()


def stopCounting(self):

i = 0

#while(1):

for i in range(100000) :

print "###############################> waiting... ", i

i = i + 1

if self.controlled.count() >= 10 :

print "it is ten"

return

####################################

class Application (object) :

def __init__(self) :

pass

def launch(self) :

self.sub = Subject()

self.control = Controller(self.sub)

self.control.start()


####################################


a = Application()

a.launch()
</code>

Comme vous pouvez le constater, le code du controlleur a été modifé : au
lieu de faire des requêtes dans une boucle wile infinie, je fais une suite
finie de requêtes, car dans le premier cas, le thread de contrôle ne
s'arrête jamais !!

Pouvez-vous m'aidez svp ??

Merci bcp.

Yacine Chaouche.

2 réponses

Avatar
F. Petitjean
On Sun, 26 Dec 2004 23:23:46 +0100, chahnaz.ourzikene wrote:
Bonjousoir,
Bonjour


Voilà, je voulais faire un peu joujou avec les threads, comme j'en avais
besoin pour une autre application, alors je me suis dis faisons un petit
teste sur un petit exemple pour bien voir si j'arrive à obtenir l'effet
désirée sur l'application finale.

J'ai besoin d'écrire un thread (controlleur) qui va inspecter l'état (disons
une variable d'état par exemple, qui dans cette exemple est un simple
compteur) d'un objet (sujet) qu'il surveil en permanence , et qui va lancer
une action (dans mon exemple, faire un print et retourner) quand la variable
d'état de l'objet surveillé vérifie une certaine condition (disons qu'elle
passe à dix ou supérieur dans mon exemple tout bête).

Le thread controlleur va donc lancer, dans une boucle while infinie, une
suite de requêtes de services sur l'objet étudié en lui demandant quelle est
la valeur de la variable d'état par m'intermediaire de la methode 'count' de
l'objet sujet. Le sujet fournit le service et lui donne la valeur de la
variable d'état. Le thread d'execution teste ensuite si cette valeur est
supérieur ou égale à dix. Si le teste est vrai, il déclanche une action
(fait un print) et retourn, sinon il réiter.


<code>
from threading import *
from threading import Thread, Timer

# sera suffisant (taper import this).

####################################

class Subject(object):

def __init__(self) :
self.counter = 0
t = Timer(0.00001,self.doIteratingStuff)
t.start()

def incrementCounter(self,n=1) :
self.counter = self.counter + n

def doIteratingStuff(self) :
for i in range(10) :
self.incrementCounter(4)
print "the counter is now", self.counter


def count(self):
return self.counter

####################################

class Controller(object):

def __init__(self, objectToControl) :
self.controlled = objectToControl
self.th = Thread(target = self.stopCounting)

def start(self):
self.th.start()


def stopCounting(self):
i = 0
#while(1):
for i in range(100000) :
# vous pourriez utiliser ici itertools.count() au lieu de générer une

# liste de 100000 entiers.
print "###############################> waiting... ", i
i = i + 1
if self.controlled.count() >= 10 :
# je verrais bien le paramètre 10 en argument de cette méthod target

print "it is ten"
return

####################################

class Application (object) :

def __init__(self) :
pass
# Si c'est pour ne mettre aucun code autant ne pas écrire de méthode

# c'est un principe général ainsi énoncé par un maître (Pierre Dac)
En politique, parler pour ne rien dire et ne rien dire pour parler sont
les deux principes majeurs de tous ceux qui feraient mieux de la fermer
avant de l'ouvrir.
# s/En politique/En programmant/

def launch(self) :
self.sub = Subject()
self.control = Controller(self.sub)
self.control.start()
return self.control.th # voir plus bas



####################################


a = Application()
a.launch()
</code>
th = a.launch()

th.join()

Comme vous pouvez le constater, le code du controlleur a été modifé : au
lieu de faire des requêtes dans une boucle wile infinie, je fais une suite
finie de requêtes, car dans le premier cas, le thread de contrôle ne
s'arrête jamais !!

Pouvez-vous m'aidez svp ??
Un thread est un fil d'exécution, une sorte de processus léger. De la

même manière que pour un processus qu'on aurait lancé par la combinaison
os.fork() + os.execvp() il faut attendre la fin avec os.waitpid(), il
convient dans le cas d'un thread d'attendre la fin par th.join(). Je
vous concède que le vocabulaire utilisé est loin d'être évident.
Dans le cas des processus la lecture du module subprocess.py (python
2.4 ou 2.3 avec une URL donnée par M Claveau) est très instructive, et
j'ai constaté que si on ne fait pas child.wait() il y a création de
processus zombies.

Merci bcp.

Yacine Chaouche.




Avatar
chahnaz.ourzikene
Merci pour les astuces du code.. et surtout la superbe citation de Pierre
Dac :) lol...

Yacine Chaouche.