取消已挂起的进程池执行器未来



我有python函数,它正在调用我无法控制或更新的C库。不幸的是,C 库存在一个间歇性错误,偶尔会挂起。为了保护我的应用程序不被挂起,我正在尝试隔离 ThreadPoolExecutor 或 ProcessPoolExecutor 中的函数调用,以便只有该线程或进程崩溃。

但是,以下代码挂起,因为执行程序无法关闭,因为进程仍在运行!

是否有可能取消前途悬而未决的遗嘱执行人?

import time
from concurrent.futures import ThreadPoolExecutor, wait
if __name__ == "__main__":
def hang_forever(*args):
print("Starting hang_forever")
time.sleep(10.0)
print("Finishing hang_forever")
print("Starting executor")
with ThreadPoolExecutor() as executor:
future = executor.submit(hang_forever)
print("Submitted future")
done, not_done = wait([future], timeout=1.0)
print("Done", done, "Not done", not_done)
# with never exits because future has hung!
if len(not_done) > 0:
raise IOError("Timeout")

文档说,在所有未决期货完成执行之前,不可能关闭执行器:

无论等待的值如何,整个 Python 程序都不会 退出,直到所有待处理期货完成执行。

拨打future.cancel()无济于事,因为它也会挂起。幸运的是,您可以通过直接使用multiprocessing.Process而不是使用ProcessPoolExecutor来解决您的问题:

import time
from multiprocessing import Process

def hang_forever():
while True:
print('hang forever...')
time.sleep(1)

def main():
proc = Process(target=hang_forever)
print('start the process')
proc.start()
time.sleep(1)
timeout = 3
print(f'trying to join the process in {timeout} sec...')
proc.join(timeout)
if proc.is_alive():
print('timeout is exceeded, terminate the process!')
proc.terminate()
proc.join()
print('done')

if __name__ == '__main__':
main()

输出:

start the process
hang forever...
trying to join the process in 3 sec...
hang forever...
hang forever...
hang forever...
hang forever...
timeout is exceeded, terminate the process!
done

最新更新