90

如果我有一个无限循环中的线程,有没有办法在主程序结束时终止它(例如,当我按Ctrl+时C)?

4

6 回答 6

113

如果你让你的工作线程守护线程,当你的所有非守护线程(例如主线程)退出时,它们就会死掉。

http://docs.python.org/library/threading.html#threading.Thread.daemon

于 2010-04-01T23:35:24.410 回答
47

检查这个问题。正确答案对如何以正确的方式终止线程有很好的解释: Is there any way to kill a Thread in Python?

要使线程在键盘中断信号 (ctrl+c) 上停止,您可以在退出之前捕获异常“KeyboardInterrupt”并进行清理。像这样:

try:
    start_thread()  
except (KeyboardInterrupt, SystemExit):
    cleanup_stop_thread()
    sys.exit()

通过这种方式,您可以控制程序突然终止时的操作。

您还可以使用内置的信号模块来设置信号处理程序(在您的特定情况下为 SIGINT 信号):http ://docs.python.org/library/signal.html

于 2010-04-01T22:51:56.217 回答
17

尝试将子线程启用为守护线程。

例如:

推荐的:

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”),其他线程也将被上述指令杀死。

于 2018-08-07T09:28:06.883 回答
12

使用 Python 标准库的atexit模块注册在主线程的任何合理“干净”终止时(在主线程上)调用的“终止”函数,包括未捕获的异常,例如KeyboardInterrupt. 这样的终止函数可能(尽管不可避免地在主线程中!)调用stop您需要的任何函数;连同将线程设置为 的可能性daemon,这为您提供了正确设计所需系统功能的工具。

于 2010-04-02T02:43:04.907 回答
9

如果您像这样生成一个线程myThread = Thread(target = function)- 然后执行myThread.start(); myThread.join(). 启动 CTRL-C 时,主线程不会退出,因为它正在等待该阻塞myThread.join()调用。要解决这个问题,只需在 .join() 调用上设置一个超时。超时时间可以根据您的意愿进行。myThread.daemon = True如果您希望它无限期地等待,只需设置一个非常长的超时时间,例如 99999。当主线程(非守护程序)退出时,所有线程都退出也是一个好习惯。

于 2013-08-13T21:25:50.530 回答
4

守护线程被不优雅地杀死,因此不会执行任何终结器指令。一种可能的解决方案是检查主线程是否处于活动状态而不是无限循环。

例如对于 Python 3:

while threading.main_thread().isAlive():
    do.you.subthread.thing()
gracefully.close.the.thread()

请参阅检查主线程是否仍然来自另一个线程

于 2019-08-21T06:08:22.323 回答