Python concurrent.futures.wait()是否保留任务提交顺序?
Python的concurrent.futures.wait()是否保留任务提交顺序?
concurrent.futures.wait()返回的done集合不会保留任务的提交顺序,这就是你遇到输出顺序不稳定的核心原因。
问题根源
wait()方法返回的done是一个无序的set集合,集合里的元素是已完成的Future对象,但它们的排列顺序和你提交任务的顺序完全无关,而是由任务实际完成的先后(或者集合内部的存储逻辑)决定的。你用mult_task, divide_task = ...done这种方式解包集合,本质是对无序集合做迭代,每次得到的Future对象顺序都是不确定的,自然会导致输出结果的顺序随机变化。
修正方案
如果你想严格按照任务提交的顺序获取结果,完全不需要依赖wait()返回的集合,直接用最初提交任务时得到的Future对象调用result()即可——因为wait()已经确保所有任务都完成了,此时调用result()不会再阻塞:
import concurrent.futures import time, random def mult(n): time.sleep(random.randrange(1,5)) return f"mult: {n * 2}" def divide(n): time.sleep(random.randrange(1,5)) return f"divide: {n // 2}" with concurrent.futures.ThreadPoolExecutor() as executor: mult_future = executor.submit(mult, 200) divide_future = executor.submit(divide, 200) # 仅等待所有任务完成,无需处理返回的集合 concurrent.futures.wait( [mult_future, divide_future], return_when=concurrent.futures.ALL_COMPLETED, ) # 直接用最初的future对象获取结果,顺序完全可控 mult_result = mult_future.result() divide_result = divide_future.result() print(mult_result) print(divide_result)
这样修改后,无论两个任务谁先执行完成,输出都会固定为:
mult: 400 divide: 50
额外说明
如果你的需求是按任务完成的先后顺序处理结果,可以使用concurrent.futures.as_completed()方法,它会迭代返回已完成的Future对象,顺序就是任务完成的先后。但如果要严格对应提交顺序,上面的方案是最直接的。
内容的提问来源于stack exchange,提问作者DevEx
相关产品推荐
相关产品推荐

