3

我想在 python 中强制线程终止:我不想设置一个事件并等到线程检查它并退出。我正在寻找一个简单的解决方案,例如kill -9. 如果没有像使用私有方法等操作这样的肮脏黑客,这是否可能做到这一点?

4

3 回答 3

1

如果你不介意你的代码运行慢十倍,你可以使用Thread2下面实现的类。下面的示例显示了调用新stop方法应如何在下一条字节码指令中终止线程。

import threading
import sys

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()

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

import time

def main():
    test = Thread2(target=printer)
    test.start()
    time.sleep(1)
    test.stop()
    test.join()

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

if __name__ == '__main__':
    main()

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

于 2014-09-05T14:38:53.597 回答
0

如果您想要的是能够让程序在其结束时终止而不关心某些线程会发生什么,那么您想要的是daemon线程。

文档

当没有活着的非守护线程时,整个 Python 程序退出。

示例使用程序:

import threading
import time

def test():
  while True:
    print "hey"
    time.sleep(1)

t = threading.Thread(target=test)
t.daemon = True # <-- set to False and the program will not terminate
t.start()
time.sleep(10)

琐事:线程在 .Netdaemon中被称为线程。background

于 2012-08-31T23:47:47.247 回答
0

线程在执行时结束。

您可以向线程发出信号,希望它尽快终止,但这假定线程中运行的代码协作,并且它不提供何时发生这种情况的上限保证。

一种经典的方法是使用变量 likeexit_immediately = False并让线程的主例程定期检查它,如果值为 . 则终止True。要让线程退出,您需要设置exit_immediately = True并调用.join()所有线程。显然,这仅在线程能够定期签入时才有效。

于 2012-08-31T23:37:46.243 回答