是否有可能终止一个正在运行的线程而不设置/检查任何标志/信号/等等?
当前回答
这是基于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")
其他回答
这似乎与windows 7上的pywin32一起工作
my_thread = threading.Thread()
my_thread.start()
my_thread._Thread__stop()
只是建立在@SCB的想法(这正是我所需要的),创建一个KillableThread子类与自定义函数:
from threading import Thread, Event
class KillableThread(Thread):
def __init__(self, sleep_interval=1, target=None, name=None, args=(), kwargs={}):
super().__init__(None, target, name, args, kwargs)
self._kill = Event()
self._interval = sleep_interval
print(self._target)
def run(self):
while True:
# Call custom function with arguments
self._target(*self._args)
# If no kill signal is set, sleep for the interval,
# If kill signal comes in while sleeping, immediately
# wake up and handle
is_killed = self._kill.wait(self._interval)
if is_killed:
break
print("Killing Thread")
def kill(self):
self._kill.set()
if __name__ == '__main__':
def print_msg(msg):
print(msg)
t = KillableThread(10, print_msg, args=("hello world"))
t.start()
time.sleep(6)
print("About to kill thread")
t.kill()
自然地,就像@SBC一样,线程不会等待运行一个新的循环来停止。在这个例子中,你会看到“kill Thread”消息紧跟在“About to kill Thread”之后,而不是等待4秒钟线程完成(因为我们已经睡了6秒了)。
KillableThread构造函数中的第二个参数是您的自定义函数(print_msg)。Args参数是在调用函数(("hello world"))时使用的参数。
你不应该在没有与线程合作的情况下强行终止线程。
杀死一个线程消除了try/finally阻塞设置的任何保证,所以你可能会让锁锁定,文件打开等等。
唯一可以认为强制终止线程是一个好主意的情况是快速终止程序,但绝不是单个线程。
没有官方API来做这个,没有。
你需要使用平台API来杀死线程,例如pthread_kill或TerminateThread。你可以访问这样的API,例如通过pythonwin,或通过ctypes。
注意,这本质上是不安全的。这可能会导致不可收集的垃圾(来自堆栈帧的局部变量,成为垃圾),并可能导致死锁,如果被杀死的线程在被杀死时具有GIL。
在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()不是选项。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 自动化invokerrequired代码模式
- 解析日期字符串并更改格式
- 使用try和。Python中的if