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")
20条答案
按热度按时间mw3dktmi16#
这是基于thread2——可终止线程(python配方)
您需要调用pythreadstate_setasyncexc(),该函数仅可通过ctypes使用。
这只在Python2.7.3上进行了测试,但它可能适用于最近的其他2.x版本。
ozxc1zmp17#
正如其他人所提到的,标准是设置停止标志。对于一些轻量级的东西(没有线程的子类,没有全局变量),lambda回调是一个选项(请注意中的括号
if stop()
.)替换
print()
用一个pr()
总是刷新的函数(sys.stdout.flush()
)可以提高外壳输出的精度。(仅在windows/eclipse/python3.3上测试)
bis0qfac18#
如果您试图终止整个程序,可以将线程设置为“守护进程”。请参阅thread.daemon
gcuhipw919#
A.
multiprocessing.Process
可以p.terminate()
如果我想杀死一个线程,但不想使用标志/锁/信号/信号量/事件/任何东西,我会将线程升级为完整的进程。对于只使用几个线程的代码,开销并没有那么大。e、 这样可以方便地终止执行阻塞i/o的助手“线程”
转换很简单:在相关代码中替换所有
threading.Thread
具有multiprocessing.Process
诸如此类queue.Queue
具有multiprocessing.Queue
并添加所需的p.terminate()
要杀死其子进程的父进程p
有关详细信息,请参阅python文档multiprocessing
.例子:
r6vfmomb20#
没有官方的api可以做到这一点。
您需要使用平台api终止线程,例如pthread_kill或terminatethread。您可以通过pythonwin或ctypes访问此类api。
请注意,这本身就是不安全的。它可能会导致无法收集的垃圾(来自成为垃圾的堆栈帧的局部变量),并可能导致死锁,如果被终止的线程在终止时具有gil。