Python - 如何正确终止/退出 Futures 线程?

11

我之前使用的是threading.Thread模块,现在我使用concurrent.futures-> ThreadPoolExecutor。以前,我使用以下代码来退出/终止/完成线程:

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

这似乎无法与futures接口一起使用。这里有什么最佳实践?只需return吗?我的线程正在控制Selenium实例。我需要确保在终止线程时,Selenium实例已被拆除。

编辑:我已经看到了被引用为重复的帖子。它不足以解决问题,因为当你涉足类似futures的东西时,行为可能会发生根本性的变化。在以前的线程模块中,我的terminate_thread函数是可以接受的,并且不适用于其他q/a的批评。这不同于“杀死”。请查看我发布的代码。

我不想杀死线程。我想检查它是否仍然存活并以最合适的方式优雅地退出线程。如何在futures中进行操作?


有人请给那个做这件事的人点个赞。我已经搜索了一下,但找不到一个例子。想要终止一个线程并不罕见或不合理。 - xendi
可能是如何在Python中终止线程的方法?的重复问题。 - Athena
1
看起来这是从 https://dev59.com/wXRC5IYBdhLWcg3wW_pk 复制的,你也实现了 StoppableThread 吗? - Athena
这里的被接受答案是关于我的futures线程如何工作的:https://stackoverflow.com/questions/52620563/python-threadpoolexecutor-blocking-how-to-unblock - xendi
1
我看到一个问题。以前我把我的线程存储在列表中,现在不再这样做了。也许我可以把 futures 存储起来并传递它们。 - xendi
显示剩余7条评论
2个回答

2

如果你想让线程完成当前的工作,请使用以下方法:

thread_executor.shutdown(wait=True)

如果您想强制取消当前正在运行的Future并停止所有...(嘿),请使用以下命令:
thread_executor.shutdown(wait=False)
for t in thread_executor._threads:
    terminate_thread(t)

使用terminate_thread函数在线程池执行器中调用异常。被中断的那些futures将返回并设置异常。


2
shutdown() 不会突然停止线程,直到“当前挂起的未来任务执行完成”。此外,使用 wait=False 仍会等待“所有挂起的未来任务执行完成”。 - howdoicode
如果 _wait 为 False_,那么这个方法将 _立即返回_,并且与执行器相关的资源将在所有待处理的 future 执行完成后被释放。 - SargeATM

-2

你需要取消每一个未来的任务,而且当前正在运行的任务也不能保证通过.cancel()方法停止。 - SargeATM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接