Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

bug etrange python

14 réponses
Avatar
ian
Salut a tous,

J'ai un bug tres etrange et je soupconne l'interpreteur (mais j'espere me
tromper)

En gros, j'ai un timeout pour changer un affichage quand on appuie sur une
touche. Le timeout est verifie dans un thread.

Appuie sur une touche > prend time.time() + 5 secondes, et stocke le dans
TOUTAffichage

Jusque la tout va bien. Mais dans le thread, 1 fois sur 20, l'incroyable se
produit, comme dit dans les logs :

2007-03-30 11:07:49,747 SKUtils DEBUG PrintScrStr: Sortie pause
2007-03-30 11:07:49,787 Process DEBUG ThreadCmd - [a passe le test] if
time.time()(1175245669.61) > TOUTAffichage(1175245674.7) and TOUTAffichage
!= 0:
2007-03-30 11:07:49,841 Process DEBUG InitBooking() - TOUTAffichage =
0

et voila le code:
a=time.time()
if (a > TOUTAffichage) and TOUTAffichage != 0:
logging.debug("ThreadCmd - [a passe le test] if time.time()(" + str(a)
+ ") > TOUTAffichage(" + str(TOUTAffichage) + ") and TOUTAffichage != 0:")
InitBooking()

en gros, a < TOUTAffichage, et TOUTAffichage est bien != 0, mais python
passe quand meme dans le IF!

Je suis dans la m.... la non ? :)

Merci

10 réponses

1 2
Avatar
hg
ian wrote:

et hop une autre thread modifie TOUTAffichage avant la trace !!


Non, tout ce qui modifie TOUTAffichage (a 4 endroits) sont logges tout
pareil.
Donc je suis sur qu'il n'est pas modifie entre temps

J'avais pense a une synchro RTC > heure systeme mais bon, perdre 5
secondes d'un coup, ca me parait gros, surtout aussi souvent :)


Par défaut Python swap tes taches toutes les 10 instructions de base: rien
n'empèche use autre tache de modifier ta variable, puis de perdre le CPU
avant que son logging ne soit exécuté.

Si TOUTAffichage est partagé par ces taches, alors (comme proposé par
Laurent) ... tu dois utiliser "threading.Lock() " lors de toute opération
que tu veux atomique.

hg


Avatar
hg
ian wrote:

Re tous,

ok au final je vais essayer les locks, meme si au final j'aime pas trop,
s'il faut tout locker, les threads n'ont plus aucune raison d'etre ..
enfin je vous apprend rien :)

Merci
+++



"hg" a écrit dans le message de news:
Bf7Ph.1948$
ian wrote:

et hop une autre thread modifie TOUTAffichage avant la trace !!


Non, tout ce qui modifie TOUTAffichage (a 4 endroits) sont logges tout
pareil.
Donc je suis sur qu'il n'est pas modifie entre temps

J'avais pense a une synchro RTC > heure systeme mais bon, perdre 5
secondes d'un coup, ca me parait gros, surtout aussi souvent :)


Par défaut Python swap tes taches toutes les 10 instructions de base:
rien n'empèche use autre tache de modifier ta variable, puis de perdre le
CPU avant que son logging ne soit exécuté.

Si TOUTAffichage est partagé par ces taches, alors (comme proposé par
Laurent) ... tu dois utiliser "threading.Lock() " lors de toute
opération que tu veux atomique.

hg




Ben je suis pas d'accord ... pour ce que ça vaut, j'ai 16 ans d'embarqué
temps réel dans les pattes (pas en Python ;-) ) ... et l'une des règle de
base dans un environement multi-thread (surtout quand ton système est
en "time-slicing"/"round robin") est que le partage des resources doit être
fait de façon atomique (ressource == donnée) ou réentrante (ressource = fontion/méthode).

Certains OS te permettent de donner des priorités à tes tâches / shunter le
time-slicing ... mais tu peux toujours te faire interrompre par une IT ...
et la rêgle ci-dessus doit ête appliquée.

En résumé tu n'a pas le choix.

Pour vérifier (partiellement) que c'est bien ton problème, passe la
granularity du swaping à une instruction ... tu verra peut-être des
plantages plus fréquents que 9/10

hg




Avatar
hg
Laurent Pointal wrote:

Re tous,

ok au final je vais essayer les locks, meme si au final j'aime pas trop,
s'il faut tout locker, les threads n'ont plus aucune raison d'etre ..
enfin je vous apprend rien :)


Il ne faut pas tout locker, il faut locker les sections critiques,
celles où tu vas modifier des variables partagées entre plusieurs
threads - sinon tu risque des incohérences, des pertes de données, des
plantages dans certains cas (genre tu testes une condition qui se
vérifie, swap de threads, un autre thread modifie tes variables et
invalide ta condition, reswap de threads, ton thread continue en
considérant une condition qui est devenue fausse).

C'est une des bases de la programmation multithreadée, tu ne pourras pas
y échapper si tu te lances là-dedans.

http://fr.wikipedia.org/wiki/Multithreading
http://fr.wikipedia.org/wiki/Synchronisation_%28multit%C3%A2ches%29

+ de nombreuses ressources sur le ouebe sur synchronisation,
multithreading, sections critiques, mutexs / locks & Co.

A+

Laurent.


Absoluement, et dans son cas, créer une fonction Set(TOUTAffichage) et
Get() / factoriser le code permettra ne n'avoir de .lock() qu'à un endroit
du code / éviter les oublies

hg


Avatar
hg
hg wrote:


Absoluement, et dans son cas, créer une fonction Set(TOUTAffichage) et
Get() / factoriser le code permettra ne n'avoir de .lock() qu'à un endroit
du code / éviter les oublies

hg



Non c'est faux et créerait un bug ... à oublier

hg

Avatar
hg
Laurent.


Absoluement, et dans son cas, créer une fonction Set(TOUTAffichage) et
Get() / factoriser le code permettra ne n'avoir de .lock() qu'à un endroit
du code / éviter les oublies

hg


parti trop vite:

Non c'est faux et créerait un bug ... à oublier
:

Set(TOUTAffichage)
Lock
TOUTAffichage = xx
Unlock


Get()
Lock
l_value = TOUTAffichage

"""
Plus de logique ici surtout si TOUTAffichage est "mutable"
"""
Unlock
return l_value


hg






hg


Avatar
Laurent Pointal
Salut a tous,

J'ai un bug tres etrange et je soupconne l'interpreteur (mais j'espere me
tromper)

En gros, j'ai un timeout pour changer un affichage quand on appuie sur une
touche. Le timeout est verifie dans un thread.

Appuie sur une touche > prend time.time() + 5 secondes, et stocke le dans
TOUTAffichage

Jusque la tout va bien. Mais dans le thread, 1 fois sur 20, l'incroyable se
produit, comme dit dans les logs :

2007-03-30 11:07:49,747 SKUtils DEBUG PrintScrStr: Sortie pause
2007-03-30 11:07:49,787 Process DEBUG ThreadCmd - [a passe le test] if
time.time()(1175245669.61) > TOUTAffichage(1175245674.7) and TOUTAffichage
!= 0:
2007-03-30 11:07:49,841 Process DEBUG InitBooking() - TOUTAffichage > 0

et voila le code:
a=time.time()
if (a > TOUTAffichage) and TOUTAffichage != 0:
logging.debug("ThreadCmd - [a passe le test] if time.time()(" + str(a)
+ ") > TOUTAffichage(" + str(TOUTAffichage) + ") and TOUTAffichage != 0:")
InitBooking()

en gros, a < TOUTAffichage, et TOUTAffichage est bien != 0, mais python
passe quand meme dans le IF!

Je suis dans la m.... la non ? :)


Bizarre...

Je ne pense pas que ça vienne de là, mais quand même:
m = threading.Lock()


try :
m.acquire()
TOUTAffichage = time.time()+ 5
finally :
m.release()




et


try :
m.acquire()
a = time.time()
go = (a > TOUTAffichage) and TOUTAffichage != 0
finally :
m.release()

if go :
...


Le joies de la programmation en multithread.

Sinon, fait une petite boucle qui stocke time.time() et regarde s'il
évolue correctement, s'il n'y a pas quelque part dans ton système un
service/démon qui recale l'horloge et irais casser ta logique.

Voir peut-être à utiliser time.clock()...

Pour des timeout, tu peux aussi regarder du côté des threading.Event()
et de leur utilisation avec des timeout (+signalisation avant le timeout
pour réarmer).


A+

Laurent.

Avatar
Méta-MCI
Bonjour !

Je ne trouve pas la cause du problème.

Mais, perso, je remplacerais :
if (a > TOUTAffichage) and TOUTAffichage != 0:
par
if (a > TOUTAffichage) and (TOUTAffichage != 0):

juste pour éviter que le and se fasse entre (a > TOUTAffichage) et
TOUTAffichage

Ce n'est pas la solution, mais ça me soulagera...

@+

MCI
Avatar
JBB
Salut a tous,

J'ai un bug tres etrange et je soupconne l'interpreteur (mais j'espere me
tromper)

En gros, j'ai un timeout pour changer un affichage quand on appuie sur une
touche. Le timeout est verifie dans un thread.

Appuie sur une touche > prend time.time() + 5 secondes, et stocke le dans
TOUTAffichage

Jusque la tout va bien. Mais dans le thread, 1 fois sur 20, l'incroyable se
produit, comme dit dans les logs :

2007-03-30 11:07:49,747 SKUtils DEBUG PrintScrStr: Sortie pause
2007-03-30 11:07:49,787 Process DEBUG ThreadCmd - [a passe le test] if
time.time()(1175245669.61) > TOUTAffichage(1175245674.7) and TOUTAffichage
!= 0:
2007-03-30 11:07:49,841 Process DEBUG InitBooking() - TOUTAffichage > 0

et voila le code:
a=time.time()
if (a > TOUTAffichage) and TOUTAffichage != 0:
et hop une autre thread modifie TOUTAffichage avant la trace !!

logging.debug("ThreadCmd - [a passe le test] if time.time()(" + str(a)
+ ") > TOUTAffichage(" + str(TOUTAffichage) + ") and TOUTAffichage != 0:")
InitBooking()

pour verifier si c'est ça t'a qu'à essayer le code suivant

a=time.time()
b = TOUTAffichage
if (a > b) and b != 0:
logging.debug("ThreadCmd - [a passe le test] if time.time()("
+ str(a)
+ ") > TOUTAffichage(" + str(TOUTAffichage) + "=?" + str(b) + ")and TOUTAffichage != 0:")
InitBooking()

en gros, a < TOUTAffichage, et TOUTAffichage est bien != 0, mais python
passe quand meme dans le IF!

Je suis dans la m.... la non ? :)

Merci




Avatar
ian
Salut,

Oui mais c'est quand meme bizarre car 9 fois sur 10 ca marche correctement
...
Pourquoi il ferait le AND a une place differente 1 fois sur 10 ?

2eme remarque, justement, quand ca marche :

2007-03-30 12:10:12,583 Process DEBUG ThreadCmd - [a passe le test] if
time.time()(1175249412.58) > TOUTAffichage(1175249412.58) and TOUTAffichage
!= 0:

ou:

2007-03-30 12:54:10,041 Process DEBUG ThreadCmd - [a passe le test] if
time.time()(1175252050.04) > TOUTAffichage(1175252050.04) and TOUTAffichage
!= 0:

la aussi le test est faux ... A n'est pas > a B, il est egal...
Le test aurait ete juste si j'avais mis >= ...
Il n'y aurait pas un probleme dans les comparaisons des floats ?
a=time.time()
print type(a)
<type 'float'>




@+++



"Méta-MCI" a écrit dans le message de
news: 460ce6f8$0$25941$
Bonjour !

Je ne trouve pas la cause du problème.

Mais, perso, je remplacerais :
if (a > TOUTAffichage) and TOUTAffichage != 0:
par
if (a > TOUTAffichage) and (TOUTAffichage != 0):

juste pour éviter que le and se fasse entre (a > TOUTAffichage) et
TOUTAffichage

Ce n'est pas la solution, mais ça me soulagera...

@+

MCI









Avatar
ian
et hop une autre thread modifie TOUTAffichage avant la trace !!


Non, tout ce qui modifie TOUTAffichage (a 4 endroits) sont logges tout
pareil.
Donc je suis sur qu'il n'est pas modifie entre temps

J'avais pense a une synchro RTC > heure systeme mais bon, perdre 5 secondes
d'un coup, ca me parait gros, surtout aussi souvent :)

1 2