Cela pourrait être une question stupide, mais je teste certaines de mes hypothèses sur Python et je ne comprends pas pourquoi l'extrait de code suivant ne se ferme pas lorsqu'il est appelé dans le thread, mais se ferme lorsqu'il est appelé dans le thread principal.
import sys, time
from threading import Thread
def testexit():
time.sleep(5)
sys.exit()
print "post thread exit"
t = Thread(target = testexit)
t.start()
t.join()
print "pre main exit, post thread exit"
sys.exit()
print "post main exit"
La documentation de sys.exit () indique que l'appel doit quitter Python. Je peux voir à partir de la sortie de ce programme que "post thread exit" n'est jamais imprimé, mais le thread principal continue juste même après que le thread appelle exit.
Une instance distincte de l'interpréteur est-elle créée pour chaque thread et l'appel à exit () quitte simplement cette instance distincte? Si tel est le cas, comment l'implémentation de thread gère-t-elle l'accès aux ressources partagées? Et si je voulais quitter le programme du fil de discussion (pas que je le veuille réellement, mais juste pour que je comprenne)?
la source
os._exit
est utilisé dans les malédictions, la console n'est pas réinitialisée à un état normal avec cela. Vous devez exécuterreset
dans le shell Unix pour résoudre ce problème.Au moins sur Linux, vous pouvez faire:
Cela envoie un
SIGINT
au thread principal qui lève unKeyboardInterrupt
. Avec cela, vous avez un bon nettoyage. Vous pouvez même gérer le signal si vous le souhaitez.BTW: Sous Windows, vous ne pouvez envoyer qu'un
SIGTERM
signal, qui ne peut pas être capturé depuis Python. Dans ce cas, vous pouvez simplement utiliseros._exit
avec le même effet.la source
Est-ce que le fait que «pre main exit, post thread exit» soit imprimé ce qui vous dérange?
Contrairement à certains autres langages (comme Java) où l'analogue à
sys.exit
(System.exit
, dans le cas de Java) provoque l'arrêt immédiat de la VM / processus / interpréteur, Pythonsys.exit
lève simplement une exception: une exception SystemExit en particulier.Voici la documentation pour
sys.exit
(justeprint sys.exit.__doc__
):Cela a quelques conséquences:
__del__
) sont potentiellement appelés lorsque les cadres de pile qui référencent ces objets sont déroulésSystemExit
exceptionLe dernier est probablement le plus surprenant, et c'est encore une autre raison pour laquelle vous ne devriez presque jamais avoir une
except
déclaration non qualifiée dans votre code Python.la source
Ma méthode préférée est la transmission de messages Erlang-ish. Légèrement simplifié, je le fais comme ceci:
la source
Queue
ici. Juste un simplebool
fera très bien. Le nom classique de cette variable estis_active
et sa valeur par défaut initiale estTrue
.bool
(ou toute autre opération atomique) fera parfaitement l'affaire pour ce problème particulier. La raison pour laquelle je vais avecQueue
s est que lorsque l'on travaille avec des agents filetés j'ai tendance à finir par avoir besoin de plusieurs signaux différents (flush
,reconnect
,exit
, etc ...) presque immédiatement.