简介
Python3.2 带来了 concurrent.futures
模块,借此能够快速使用线程池和进程池。
对于不需要控制优先级与资源分配的多任务,使用 concurrent.futures
模块快捷优雅。
示例代码与效果
import concurrent.futures
import time
def a_task(x):
"""模拟一个耗时的任务"""
def count(number) :
for i in range(0, 10000000):
i=i+1
return i * number
result_item = count(x)
return result_item
number_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
if __name__ == "__main__":
# 顺序执行
start_time = time.time()
for item in number_list:
print(a_task(item))
print("Sequential execution in " + str(time.time() - start_time), "seconds")
# 线程池执行
start_time_1 = time.time()
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(a_task, item) for item in number_list]
for future in concurrent.futures.as_completed(futures):
print(future.result())
print ("Thread pool execution in " + str(time.time() - start_time_1), "seconds")
# 进程池
start_time_2 = time.time()
with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(a_task, item) for item in number_list]
for future in concurrent.futures.as_completed(futures):
print(future.result())
print ("Process pool execution in " + str(time.time() - start_time_2), "seconds")
运行后可以查看各种方案的耗时。ThreadPoolExecutor
比直接执行快一些。ProcessPoolExecutor
可以不受 GIL 限制,极大缩短执行时间。
使用线程池和进程池
以进程池为例。
要开始使用进行池,首先需要创建一个 executor,用于存放与管理任务。
with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
这里可以用 max_workers
指定并行执行数量,默认为 CPU 核心数。
使用 .submit()
将任务送入到 executor 池中。.submit()
会返回一个 future 对象,这代表已经放入池中的、待完成的任务。
future = executor.submit(some_func, param1, param2)
现在就能够用 .result()
让这一个 future 执行,并获取结果。与直接调用 some_func
不同,这是在进程池里执行的。
result = future.result()
若现在手头有一大堆的 future,那就使用 concurrent.future.as_completed()
全部执行。这会让 executor 参与多进程调度,同时执行多个 future。
for future in concurrent.futures.as_completed(futures):
print(future.result())
参考来源
- 深度学习可好玩了,“python并发编程入门:(四)concurrent.futures”,https://zhuanlan.zhihu.com/p/438627177
- “2. 使用Python的 concurrent.futures 模块”,https://python-parallel-programmning-cookbook.readthedocs.io/zh-cn/latest/chapter4/02_Using_the_concurrent.futures_Python_modules.html