Python的`concurrent.futures`:根据完成顺序迭代期货

Ram*_*hum 21 python multithreading future

我想要类似的东西executor.map,除非我迭代结果,我想根据完成的顺序迭代它们,例如,首先完成的工作项应首先出现在迭代中,等等.这样迭代将是阻止iff序列中的每个工作项尚未完成.

我知道如何使用队列自己实现这个,但我想知道是否可以使用该futures框架.

(我主要使用基于线程的执行程序,所以我想要一个适用于这些的答案,但一般的答案也会受到欢迎.)

更新:谢谢你的答案!你能解释我怎么as_completedexecutor.map吗?executor.map在使用期货时,对我来说是最实用和最简洁的工具,我不愿意Future手动开始使用对象.

gnr*_*gnr 37

executor.map()和内置map()函数一样,只返回迭代次序的结果,所以不幸的是你不能用它来确定完成的顺序.concurrent.futures.as_completed()是你在找什么 - 这是一个例子:

import time
import concurrent.futures

times = [3, 1, 2]

def sleeper(secs):
    time.sleep(secs)
    print('I slept for {} seconds'.format(secs))
    return secs

# returns in the order given
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    print(list(executor.map(sleeper, times)))

# I slept for 1 seconds
# I slept for 2 seconds
# I slept for 3 seconds
# [3, 1, 2]

# returns in the order completed
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    futs = [executor.submit(sleeper, secs) for secs in times]
    print([fut.result() for fut in concurrent.futures.as_completed(futs)])

# I slept for 1 seconds
# I slept for 2 seconds
# I slept for 3 seconds
# [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

当然,如果您需要使用地图界面,您可以创建自己的map_as_completed()功能,封装上面的内容(可能将其添加到子类Executor()),但我认为创建期货实例executor.submit()是一种更简单/更清晰的方式(也允许你提供no-args,kwargs).