是否有可能终止一个正在运行的线程而不设置/检查任何标志/信号/等等?


当前回答

使用setDaemon(True)启动子线程。

def bootstrap(_filename):
    mb = ModelBootstrap(filename=_filename) # Has many Daemon threads. All get stopped automatically when main thread is stopped.

t = threading.Thread(target=bootstrap,args=('models.conf',))
t.setDaemon(False)

while True:
    t.start()
    time.sleep(10) # I am just allowing the sub-thread to run for 10 sec. You can listen on an event to stop execution.
    print('Thread stopped')
    break

其他回答

如果您试图终止整个程序,您可以将线程设置为“守护进程”。看到 Thread.daemon

如果您确实需要终止子任务的能力,请使用另一种实现。Multiprocessing和gevent都支持不加选择地杀死一个“线程”。

Python的线程不支持取消。不要尝试。你的代码很可能死锁、损坏或泄漏内存,或者有其他意想不到的“有趣的”难以调试的效果,这种情况很少发生,而且不确定。

可以通过在将退出线程的线程中安装trace来终止线程。请参阅所附的链接,了解一种可能的实现。

在Python中杀死一个线程

我想补充的一件事是,如果你阅读threading lib Python的官方文档,建议避免使用“恶魔”线程,当你不希望线程突然结束时,带有Paolo Rovelli提到的标志。

来自官方文件:

守护进程线程在关机时突然停止。它们的资源(如打开的文件、数据库事务等)可能无法正确释放。如果您希望线程优雅地停止,请将它们设置为非守护进程,并使用适当的信号机制(如Event)。

我认为创建守护线程取决于您的应用程序,但通常(在我看来)最好避免杀死它们或使它们成为守护线程。在多处理中,您可以使用is_alive()来检查进程状态,并使用“terminate”来完成它们(也可以避免GIL问题)。但有时,当你在Windows中执行代码时,你会发现更多的问题。

并且永远记住,如果你有“活动线程”,Python解释器将运行等待它们。(因为这个守护程序可以帮助你如果不重要的事情突然结束)。

多处理。进程可以p.terminate()

如果我想杀死一个线程,但不想使用标志/锁/信号/信号量/事件/任何东西,我就把线程提升到完整的进程。对于只使用几个线程的代码,开销并没有那么糟糕。

例如,这可以方便地终止执行阻塞I/O的助手“线程”

转换很简单:在相关代码中替换所有线程。多线程线程。进程和所有队列。多处理队列。排队并将p.t terminate()所需的调用添加到想要杀死子进程p的父进程中

关于多处理,请参阅Python文档。

例子:

import multiprocessing
proc = multiprocessing.Process(target=your_proc_function, args=())
proc.start()
# Terminate the process
proc.terminate()  # sends a SIGTERM