2

Selon l'instruction the official python documentation, l'instruction "finally" sera toujours exécutée et sera donc généralement utilisée pour les opérations de nettoyage.L'instruction finally ne prend pas effet dans un thread

Si "finally" est présent, il spécifie un gestionnaire de "nettoyage". La clause "try" est exécutée, y compris les clauses "except" et "else". Si une exception se produit dans l'une des clauses et n'est pas gérée, l'exception est temporairement enregistrée. La clause "finally" est exécutée. S'il existe une exception enregistrée, elle est relancée à la fin de la clause "finally". Si la clause « enfin » soulève une autre exception ou exécute une instruction de retour ou la rupture, l'exception enregistrée est mis au rebut:

Cependant, quand je mis en œuvre l'énoncé « try-finally » dans un fil, « enfin » partie semble ne pas être exécuté.

from __future__ import print_function 
import threading 
def thread1(): 
    try: 
     while True: 
      pass 
    except: 
     print("exception") 
    finally: 
     print("closed") 

t = threading.Thread(target = thread1) 
t.setDaemon(True) 
t.start() 
while True: 
    pass 

En cas d'interruption par ctrl-c, "fermé" n'est pas imprimé sur l'écran. Pourquoi donc?

Alors que dans le code suivant "enfin" fonctionne (sans surprise)

from __future__ import print_function 
try: 
    while True: 
     pass 
finally: 
    print("closed") 

Répondre

2

Dans the documentation pour le module thread (qui sous-tend threading):

Lorsque les sorties principales de filetage, il est Système selon si les autres fils survivent. Sur SGI IRIX utilisant l'implémentation de thread natif, ils survivent. Sur la plupart des autres systèmes, ils sont supprimés sans exécuter les clauses try ... finally ou exécuter des destructeurs d'objets.

+1

Merci! Alors, comment dois-je faire un nettoyage pour un fil? –

+0

Signal d'interception.SIGINT dans le thread principal et à partir de son gestionnaire envoie tous les messages fils enfants à nettoyer et arrêter. Le moyen le plus simple serait une variable globale partagée que les threads enfants vérifient dans leur boucle principale. – void

+0

Que faire si les threads enfants bloquent l'attente d'une entrée (par exemple, à partir du réseau). – user48956

-1

CTRL + C tue le script, à savoir qu'il cesse de fonctionner et rien d'autre traitera.

+0

Cela ne répond pas à la question. En outre, ce n'est pas vrai. vous pouvez intercepter un KeyboardInterrupt et poursuivre le traitement. –