La façon la plus simple est de commencer tous les threads de travail comme fils de démon, puis ont tout simplement votre boucle principale soit
while True:
sleep(1)
Frapper les touches Ctrl + C lancera une exception dans votre thread principal, et tout des threads démon sortira à la sortie de l'interpréteur. Cela suppose que vous ne voulez pas effectuer de nettoyage dans tous ces threads avant qu'ils ne quittent.
Une façon plus complexe est d'avoir une approche globale stopped
Event:
stopped = Event()
def worker():
while not stopped.is_set():
try:
item = q.get_nowait()
do_work(item)
except Empty: # import the Empty exception from the Queue module
stopped.wait(1)
Ensuite, votre boucle principale peut régler le stopped
événement à False
quand il obtient un KeyboardInterrupt
try:
while not stopped.is_set():
stopped.wait(1)
except KeyboardInterrupt:
stopped.set()
Cela permet à votre travailleur les threads finissent ce qu'ils veulent faire au lieu de simplement avoir chaque thread de travail comme démon et de sortir au milieu de l'exécution. Vous pouvez également faire le nettoyage que vous voulez.
Notez que cet exemple n'utilise pas q.join()
- cela rend les choses plus complexes, bien que vous puissiez toujours l'utiliser. Si vous faites alors votre meilleur pari est d'utiliser des gestionnaires de signal au lieu d'exceptions pour détecter KeyboardInterrupt
s. Par exemple:
from signal import signal, SIGINT
def stop(signum, frame):
stopped.set()
signal(SIGINT, stop)
Cela vous permet de définir ce qui se passe lorsque vous appuyez sur Ctrl + C sans affecter quel que soit votre boucle principale est au milieu de. Donc, vous pouvez continuer à faire q.join()
sans vous soucier d'être interrompu par un Ctrl + C. Bien sûr, avec mes exemples ci-dessus, vous n'avez pas besoin de vous joindre, mais vous pourriez avoir une autre raison de le faire.
Donc, en gros, l'utilisation de q.join() rend difficile la gestion des exceptions dans les threads? –
Ne devrait-il pas lire "signal (SIGINT, stop)"? – Ber
Cela rend les choses plus complexes, mais j'ai ajouté un exemple avec des signaux pour vous montrer comment vous utiliseriez q.join() si vous aviez une bonne raison de l'utiliser. –