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


当前回答

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

在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()不是选项。

你不应该在没有与线程合作的情况下强行终止线程。

杀死一个线程消除了try/finally阻塞设置的任何保证,所以你可能会让锁锁定,文件打开等等。

唯一可以认为强制终止线程是一个好主意的情况是快速终止程序,但绝不是单个线程。

实现一个线程是绝对可能的。方法,如下例代码所示:

import sys
import threading
import time


class StopThread(StopIteration):
    pass

threading.SystemExit = SystemExit, StopThread


class Thread2(threading.Thread):

    def stop(self):
        self.__stop = True

    def _bootstrap(self):
        if threading._trace_hook is not None:
            raise ValueError('Cannot run thread with tracing!')
        self.__stop = False
        sys.settrace(self.__trace)
        super()._bootstrap()

    def __trace(self, frame, event, arg):
        if self.__stop:
            raise StopThread()
        return self.__trace


class Thread3(threading.Thread):

    def _bootstrap(self, stop_thread=False):
        def stop():
            nonlocal stop_thread
            stop_thread = True
        self.stop = stop

        def tracer(*_):
            if stop_thread:
                raise StopThread()
            return tracer
        sys.settrace(tracer)
        super()._bootstrap()

###############################################################################


def main():
    test1 = Thread2(target=printer)
    test1.start()
    time.sleep(1)
    test1.stop()
    test1.join()
    test2 = Thread2(target=speed_test)
    test2.start()
    time.sleep(1)
    test2.stop()
    test2.join()
    test3 = Thread3(target=speed_test)
    test3.start()
    time.sleep(1)
    test3.stop()
    test3.join()


def printer():
    while True:
        print(time.time() % 1)
        time.sleep(0.1)


def speed_test(count=0):
    try:
        while True:
            count += 1
    except StopThread:
        print('Count =', count)

if __name__ == '__main__':
    main()

Thread3类运行代码的速度似乎比Thread2类快大约33%。