`ThreadPoolExecutor.shutdown` 不起作用,代码无限期地卡住

问题描述 投票:0回答:1

如果在其中一个线程执行期间发生特定异常,我需要能够暂停所有线程,或者立即终止所有线程。

from concurrent.futures import ThreadPoolExecutor, as_completed
from time import sleep


class ThreadTerminationRequired(Exception):
    pass


def work(i):
    if i in range(50, 100):
        raise ThreadTerminationRequired
    print(f'sleeping for {i}')
    sleep(i)


if __name__ == '__main__':
    with ThreadPoolExecutor(64) as executor:
        futures = {executor.submit(work, i): i for i in range(1000)}

        try:
            for future in as_completed(futures):
                future.result()
        except ThreadTerminationRequired:
            executor.shutdown(wait=False, cancel_futures=True)

显然

wait=False
cancel_futures=True
是无用的,不指定其中任何一个或两者都会导致相同的结果。我也尝试过:

for future in futures:
    future.cancel()

无论哪种方式,当我需要立即终止时,代码都会卡住。另外,我不想使用

sys.exit
,因为如果发生
ThreadTerminationRequired
,我将需要进行更改,然后重新启动所有线程。即使这样,使用
exit(1)
sys.exit(1)
也能得到相同的结果。

python multithreading threadpoolexecutor concurrent.futures
1个回答
0
投票

shutdown
的行为在docs中进行了描述:

向执行器发出信号,表明当前待处理的 future 执行完毕后,它应该释放正在使用的所有资源。

所有已待处理的期货将继续运行。

还有:

无论 wait 的值是多少,在所有挂起的 future 执行完毕之前,整个 Python 程序都不会退出。

和:

如果 cancel_futures 和 wait 都为 True,则执行器已开始运行的所有 future 都将在此方法返回之前完成。剩余的期货被取消。

简而言之,这只会停止尚未开始的期货。

要停止正在运行的线程,您可以使用Events之类的东西,并在设置某个关闭事件时关闭线程。这将要求您定期检查事件的状态。

还有多种其他方法可以杀死线程,但这完全取决于您的具体需求。

© www.soinside.com 2019 - 2024. All rights reserved.