如果我在无限循环中有一个线程,是否有办法在主程序结束时(例如,当我按Ctrl+时C)终止它?
Answers:
检查这个问题。正确的答案对如何以正确的方式终止线程有很好的解释: 有没有办法杀死Python中的线程?
要使线程在键盘中断信号(ctrl + c)上停止,您可以在退出之前捕获异常“ KeyboardInterrupt”并进行清除。像这样:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
这样,您可以控制程序突然终止时的处理方式。
您还可以使用内置的信号模块,该模块可用于设置信号处理程序(在特定情况下为SIGINT信号):http : //docs.python.org/library/signal.html
cleanup_stop_thread()
一个全球性的功能,我可以使用?还是我需要实施它?
如果使工作线程守护程序线程成为线程,则当所有非守护程序线程(例如主线程)退出时它们将死亡。
http://docs.python.org/library/threading.html#threading.Thread.daemon
isDaemon()
为False,请通过设置为True setDaemon(True)
。
isDaemon()
和setDaemon()
老getter / setter方法(根据连接的文档以上),只是使用daemon=True
在threading.Thread()
尝试将子线程启用为守护程序线程。
推荐的:
from threading import Thread
t = Thread(target=<your-method>)
t.daemon = True # This thread dies when main thread (only non-daemon thread) exits.
t.start()
排队:
t = Thread(target=<your-method>, daemon=True).start()
旧API:
t.setDaemon(True)
t.start()
当您的主线程终止时(例如,当我按Ctrl+时C),其他线程也将被上述说明杀死。
使用Python标准库的atexit模块来注册在主线程的任何合理的“干净”终止(包括未捕获的异常)上调用(在主线程上)的“终止”函数KeyboardInterrupt
。这样的终止函数可以(尽管不可避免地在主线程中!)调用stop
您需要的任何函数;加上将线程设置为的可能性daemon
,可以为您提供正确设计所需系统功能的工具。
atexit.register()
Python模块中的延迟调用会导致发生奇怪的事情,从而导致终止过程在的执行之后执行multiprocessing
。我在处理Queue
和daemon
线程方面遇到了这个问题:使用多重处理Queue和Thread在程序退出时出现“ EOF错误”。
atexit
当非守护程序线程处于活动状态并且主线程退出时,不会调用处理程序。请参阅使用atexit终止线程时脚本卡在出口上。
如果您像这样生成一个线程myThread = Thread(target = function)
,然后执行myThread.start(); myThread.join()
。启动CTRL-C时,主线程不会退出,因为它正在等待该阻塞myThread.join()
调用。要解决此问题,只需在.join()调用中添加超时即可。超时时间可以是您希望的时间。如果希望它无限期地等待,只需设置一个非常长的超时(如99999)即可。这样做也是一种好习惯,myThread.daemon = True
当主线程(非守护程序)退出时,所有线程都退出。
myThread.daemon = True
是解决这个问题的绝妙方法。
.daemon=True
并不是一个解决方案。检查该线程以获取解释:stackoverflow.com/a/20598791/5562492
守护进程线程被恶意破坏,因此不会执行任何终结器指令。一个可能的解决方案是检查主线程是否仍然存在而不是无限循环。
例如Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
请参阅检查主线程是否仍在另一个线程中。