如果您想在结果完成时使用它们而不保留原始 iterable 的顺序,您可以使用executor.submit
with concurrent.futures.as_completed
:
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
import random
def fct(variable1, variable2):
time.sleep(random.randint(1,5))
return variable1+1, variable2+1
variables1 = [1,2,3,4]
variables2 = [7,8,9,0]
with ThreadPoolExecutor(max_workers = 8) as executor:
for out in as_completed([executor.submit(fct,*vars)
for vars in zip(variables1, variables2)]):
print(out.result())
输出(尽管在任何给定的运行中都可能有任何顺序,因为random.randint
):
(4, 10)
(5, 1)
(2, 8)
(3, 9)
as_completed
Future
只要它被标记为完成,就会从它的输入列表中产生一个Future
,不管它实际上在输入列表中的哪个位置。这样,如果第二项在 2 秒后完成,但第一项需要 15 秒,您将在 2 秒后看到第二项的结果,而不是需要等待 15 秒。这可能是也可能不是理想的行为,具体取决于您的特定用例。
编辑:
请注意,您仍然可以通过这种方式获得原始顺序的输出。您只需要保存您提供给的列表as_completed
:
with ThreadPoolExecutor(max_workers = 8) as executor:
jobs = [executor.submit(fct, *vars)
for vars in zip(variables1, variables2)]
for out in as_completed(jobs):
print(out.result())
results = [r.result() for r in jobs]
print(results)
输出:
(5, 1)
(2, 8)
(3, 9)
(4, 10)
[(2, 8), (3, 9), (4, 10), (5, 1)]