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


当前回答

这是基于thread2—可杀死线程ActiveState配方。

您需要调用PyThreadState_SetAsyncExc(),它只能通过ctypes模块使用。

这只在Python 2.7.3上进行了测试,但它很可能与最近的其他2一起工作。x版本。PyThreadState_SetAsyncExc()仍然存在于Python 3中以实现向后兼容性(但我还没有测试它)。

import ctypes

def terminate_thread(thread):
    """Terminates a python thread from another thread.

    :param thread: a threading.Thread instance
    """
    if not thread.isAlive():
        return

    exc = ctypes.py_object(SystemExit)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
        ctypes.c_long(thread.ident), exc)
    if res == 0:
        raise ValueError("nonexistent thread id")
    elif res > 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

其他回答

下面的方法可以用来杀死一个线程:

kill_threads = False

def doSomething():
    global kill_threads
    while True:
        if kill_threads:
            thread.exit()
        ......
        ......

thread.start_new_thread(doSomething, ())

这甚至可以用于从主线程终止代码写在另一个模块中的线程。我们可以在该模块中声明一个全局变量,并使用它来终止在该模块中生成的线程。

我通常使用它在程序出口终止所有线程。这可能不是终止线程的完美方法,但可能有帮助。

在Python中,你不能直接杀死一个线程。

如果你不是真的需要Thread(!),你可以做的,而不是使用threading包,是使用 多处理包。在这里,要终止一个进程,你可以简单地调用方法:

yourProcess.terminate()  # kill the process!

Python将终止您的进程(在Unix上通过SIGTERM信号,而在Windows上通过TerminateProcess()调用)。注意在使用队列或管道时使用它!(可能会破坏队列/管道中的数据)

注意,多处理。事件和多处理。信号量的工作方式与线程完全相同。事件和线程。信号量分别。事实上,前者是后者的克隆。

如果你真的需要使用一个线程,没有办法直接杀死它。但是,您可以使用“守护线程”。事实上,在Python中,线程可以被标记为守护进程:

yourThread.daemon = True  # set the Thread as a "daemon thread"

当没有活动的非守护进程线程时,主程序将退出。换句话说,当主线程(当然是非守护线程)完成其操作时,即使仍有一些守护线程在工作,程序也将退出。

注意,在调用start()方法之前,有必要将线程设置为守护进程!

当然,你可以,也应该在多进程中使用daemon。在这里,当主进程退出时,它将尝试终止其所有守护子进程。

最后,请注意sys.exit()和os.kill()不是选项。

多处理。进程可以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

这是一个糟糕的答案,请看评论

以下是如何做到这一点:

from threading import *

...

for thread in enumerate():
    if thread.isAlive():
        try:
            thread._Thread__stop()
        except:
            print(str(thread.getName()) + ' could not be terminated'))

给它几秒钟,然后你的线程应该停止。还要检查thread._Thread__delete()方法。

为了方便,我建议使用thread.quit()方法。例如,如果你的线程中有一个套接字,我建议在你的套接字句柄类中创建一个quit()方法,终止套接字,然后在你的quit()中运行一个thread. _thread__stop()。

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