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

Stoper une boucle de threading.Thread

4 réponses
Avatar
Laurent Claessens
Salut à toutes et à tous



J'ai une liste de choses à faire dans des threads différents. L'idée
de base est de faire ceci:

for task in list_to_do:
taks.run()


Je voudrais que les tâches puissent lever certaines exceptions qui font
stopper la boucle. J'ai essayé ceci :

tout_va_bien = True
while list_to_do and tout_va_bien:
task = list_to_do[0]
list_to_do.remove(task)
try:
taks.run()
except IOError :
tout_va_bien = False


Même lorsque mes tâches lèvent IOError, la boucle ne s'arrête pas. Il me
semble que le except arrive chronologiquement trop tôt : il faut un peu
de temps à la tâche pour lever l'exception.

Question : comment fait pour qu'une tâche en threading puisse faire
stopper le programme entier ?
De préférence, j'aimerais que la tâche ne soit pas consciente d'être
dans la boucle.

merci
Bonne fin de WE
Laurent

4 réponses

Avatar
Alain Ketterlin
Laurent Claessens writes:

for task in list_to_do:
taks.run()



run() ou start() ?

Je voudrais que les tâches puissent lever certaines exceptions qui
font stopper la boucle. J'ai essayé ceci :

tout_va_bien = True
while list_to_do and tout_va_bien:
task = list_to_do[0]
list_to_do.remove(task)
try:
taks.run()
except IOError :
tout_va_bien = False



Supposons que run() soit en fait start().

Même lorsque mes tâches lèvent IOError, la boucle ne s'arr ête pas. Il
me semble que le except arrive chronologiquement trop tôt : il faut un
peu de temps à la tâche pour lever l'exception.



Non. Chaque thread a sa propre pile, et un thread ne peut pas voir les
exceptions levées par un autre thread

Question : comment fait pour qu'une tâche en threading puisse faire
stopper le programme entier ?



Il y a plusieurs solutions : 1) un flag global positionné par le thread
fautif et consulté par le thread principal, 2) un attribut dans chaque
thread indiquant s'il y eu une erreur, et consulté par le thread
principal au moment du join() (tu appelles join() de temps en temps,
n'est-ce pas ?), 3) ...

De préférence, j'aimerais que la tâche ne soit pas conscie nte d'être
dans la boucle.



Oui mais il faudra bien qu'elle indique d'une façon ou d'une autre
qu'elle a échoué.

-- Alain.
Avatar
Laurent Claessens
Le 19/06/2011 18:13, Alain Ketterlin a écrit :
Laurent Claessens writes:

for task in list_to_do:
taks.run()



run() ou start() ?




start()


Il y a plusieurs solutions : 1) un flag global positionné par le thread
fautif et consulté par le thread principal, 2) un attribut dans chaque
thread indiquant s'il y eu une erreur, et consulté par le thread
principal au moment du join() (tu appelles join() de temps en temps,
n'est-ce pas ?), 3) ...



Solution 1) adoptée, merci.

En lisant de la doc plus avant, j'ai remarqué qu'il était difficile de
tuer des processus. Pas grave.

Non, je n'appelle pas join() de temps en temps. Pourquoi le ferais-je ?
Tous mes processus sont indépendants. À part les erreurs, y'en a pas un
qui dépend d'un autre.

Merci
Laurent
Avatar
Alain Ketterlin
Laurent Claessens writes:

[...]
Non, je n'appelle pas join() de temps en temps. Pourquoi le ferais-je
? Tous mes processus sont indépendants. À part les erreurs, y'e n a pas
un qui dépend d'un autre.



Comment sais-tu que le travail est fini ? Imagine que tu sortes de ta
boucle, et qu'après cela un thread provoque une erreur.

Au passage, si tu lances des threads à toute vitesse tu as beaucoup de
chance de provoquer des erreurs (manque de ressources) et/ou de
provoquer tant de contention que ton programme va se mettre à crawler
(surtout si ils tapent tous sur le même disque).

-- Alain.
Avatar
Alain Ketterlin
Laurent Claessens writes:

Je ne sors pas de la boucle avant que tout soit fini. Je teste
task.isAlive() régulièrement.



Précisément : task.join() te permettrait d'attendre tranquillemen t que
ça se termine (sans boucler sur un sleep, par exemple).

Pas de problèmes : je ne lance que deux processus en même temps : un
qui lit sur un disque et un qui écrit sur un autre disque.



Ton système ressemble fort à un producteur/consommateur, cf.
http://en.wikipedia.org/wiki/Producer-consumer_problem

Cela dit, j'avoue que je n'ai pas regardé ton code dans le détail.

-- Alain.