在Python中用concurrent.futures创建线程池进程池

简介

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())

参考来源

posted @ 2024-04-05 18:18  倒地  阅读(10)  评论(0编辑  收藏  举报