并发编程的实用工具:concurrent.futuresas_completed()函数详解
concurrent.futures是Python标准库中用于进行并发编程的模块,提供了一种简单的方式来实现多线程和多进程的并发执行。其中,concurrent.futures.as_completed()函数是一个实用工具,用于管理多个并发任务的完成顺序。
as_completed()函数可以接受一个迭代器参数,迭代器中包含了已经提交给线程池的并发任务。as_completed()函数返回一个生成器,当任务完成时会产生一个Future对象,可以使用next()函数来获取这个Future对象,然后通过Future对象的result()方法来获取任务的返回值。
下面给出一个具体的例子,首先需要导入concurrent.futures模块和time模块:
import concurrent.futures import time
然后定义一个函数,模拟一个耗时的任务。这个函数接受一个参数n,表示任务的编号,然后打印出任务开始的信息,并使用time.sleep()函数来模拟一个耗时的任务,最后返回任务的编号和执行时间。
def task(n):
print(f"Task {n} started")
time.sleep(2)
print(f"Task {n} finished")
return n, time.time()
接下来,创建一个ThreadPoolExecutor对象,设置最大线程数为3:
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
然后使用executor.submit()函数提交一系列任务,返回每个任务的Future对象,并将这些Future对象保存在一个列表中:
futures = [executor.submit(task, i) for i in range(10)]
最后,使用as_completed()函数根据任务的完成顺序来获取任务的返回值,并打印出来:
for future in concurrent.futures.as_completed(futures):
result = future.result()
print(result)
运行上述代码,可以看到任务的执行顺序可能是乱序的,但是在获取任务的返回值时,是按照任务完成的顺序来获取的。例如,输出可能是:
Task 0 started Task 1 started Task 2 started Task 0 finished (0, 1567698707.7404308) Task 3 started (1, 1567698707.7404308) Task 4 started Task 1 finished (2, 1567698707.7404308) Task 2 finished Task 5 started ...
从输出中可以看出,任务的执行是并发的,但是获取任务的返回值是按照任务的完成顺序来获取的。
as_completed()函数可以用于任何实现了线程池接口的并发框架,不仅仅局限于concurrent.futures模块。它是一个非常实用的工具,用于管理多个并发任务的返回顺序,可以在实际的并发编程中发挥重要作用。
