我正在尝试在 Windows 7 上的 Python 3.6 中使用 ThreadPoolExecutor,异常似乎被忽略或停止程序执行。示例代码:
#!/usr/bin/env python3
from time import sleep
from concurrent.futures import ThreadPoolExecutor
EXECUTOR = ThreadPoolExecutor(2)
def run_jobs():
EXECUTOR.submit(some_long_task1)
EXECUTOR.submit(some_long_task2, 'hello', 123)
return 'Two jobs was launched in background!'
def some_long_task1():
print("Task #1 started!")
for i in range(10000000):
j = i + 1
1/0
print("Task #1 is done!")
def some_long_task2(arg1, arg2):
print("Task #2 started with args: %s %s!" % (arg1, arg2))
for i in range(10000000):
j = i + 1
print("Task #2 is done!")
if __name__ == '__main__':
run_jobs()
while True:
sleep(1)
输出:
Task #1 started!
Task #2 started with args: hello 123!
Task #2 is done!
它一直卡在那里,直到我用 Ctrl+C 杀死它。
但是,当我从 some_long_task1 中删除 1/0 时,任务 #1 顺利完成:
Task #1 started!
Task #2 started with args: hello 123!
Task #1 is done!
Task #2 is done!
我需要捕获在 ThreadPoolExecutor 中运行的函数中引发的异常以某种方式。
Python 3.6 (Minconda),Windows 7 x64。
请您参考如下方法:
ThreadPoolExecutor.submit返回 future object表示计算结果,一旦可用。为了不忽略作业引发的异常,您需要实际访问此结果。首先,您可以更改 run_job 以返回创建的 future :
def run_jobs():
fut1 = EXECUTOR.submit(some_long_task1)
fut2 = EXECUTOR.submit(some_long_task2, 'hello', 123)
return fut1, fut2
然后,有顶层代码wait为 future 完成,并访问他们的结果:
import concurrent.futures
if __name__ == '__main__':
futures = run_jobs()
concurrent.futures.wait(futures)
for fut in futures:
print(fut.result())
在执行引发异常的 future 调用 result() 会将异常传播给调用者。在这种情况下,ZeroDivisionError 将在顶层引发。
