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


当前回答

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

在Python中杀死一个线程

其他回答

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

没有官方API来做这个,没有。

你需要使用平台API来杀死线程,例如pthread_kill或TerminateThread。你可以访问这样的API,例如通过pythonwin,或通过ctypes。

注意,这本质上是不安全的。这可能会导致不可收集的垃圾(来自堆栈帧的局部变量,成为垃圾),并可能导致死锁,如果被杀死的线程在被杀死时具有GIL。

使用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的子类化,没有全局变量),lambda回调是一个选项。(注意if stop()中的括号。)

import threading
import time

def do_work(id, stop):
    print("I am thread", id)
    while True:
        print("I am thread {} doing something".format(id))
        if stop():
            print("  Exiting loop.")
            break
    print("Thread {}, signing off".format(id))


def main():
    stop_threads = False
    workers = []
    for id in range(0,3):
        tmp = threading.Thread(target=do_work, args=(id, lambda: stop_threads))
        workers.append(tmp)
        tmp.start()
    time.sleep(3)
    print('main: done sleeping; time to stop the threads.')
    stop_threads = True
    for worker in workers:
        worker.join()
    print('Finis.')

if __name__ == '__main__':
    main()

将print()替换为始终刷新的pr()函数(sys.stdout.flush())可以提高shell输出的精度。

(仅在Windows/Eclipse/Python3.3上测试)

有一个图书馆就是为了这个目的而建的,别说了。尽管这里列出的一些注意事项仍然适用,但至少这个库提供了一种常规的、可重复的技术来实现既定的目标。