concurrent模块之Executor类

295 阅读2分钟

python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码。此外,从3.2版本开始,标准库还提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threading和multiprocessing模块更高级的抽象,直接支持编写线程池/进程池。

Executor是一个抽象类,它不能被直接使用。它为具体的异步执行定义了一些基本的方法。ThreadPoolExecutor和ProcessPoolExecutor继承了Executor,分别被用来创建线程池和进程池的代码

1 ThreadPoolExecutor对象

ThreadPoolExecutor类是Executor的子类,使用线程池执行异步调用。

ThreadPoolExecutor(max_workers)

使用max_workers数目的线程池执行异步调用

2 ProcessPoolExecutor对象

ProcessPoolExecutor类是Executor的子类,使用进程池执行异步调用。

ProcessPoolExecutor(max_workers)

使用max_workers数目的进程池执行异步调用,如果max_workers的值为None,则使用机器的处理器数目(如8核的机器就使用8个进程进行异步并发)

3 submit()方法

3.1 方法介绍

该方法的作用是提交一个可执行的回调task,返回一个future实例。future对象代表给定的调用。

Executor.submit(fn, *args, **kwargs)

fn:需要异步执行的函数

*args, **kwargs:传递给fn的参数

3.2 使用实例

from concurrent import futures
import time
​
​
def test(num):
    return time.ctime(), num
​
​
with futures.ThreadPoolExecutor(max_workers=3) as executor:
    future = executor.submit(test, 2)
    print(future.result())

result:

('Sun Jan 16 12:23:38 2022', 2)

4 map()方法

4.1 方法介绍

该方法返回一个map(func, *iterables)迭代器,迭代器中的回调执行返回的结果是有序的。

Executor.map(fn, *iterables, timeout=None)

fn:需要异步执行的函数

iterables:可迭代对象。每一次func执行,都会从iterables中读取参数。

timeout:设置每次异步操作的超时时间,取值可以是int或者float。若操作超时,则返回raisesTimeoutError

4.2 使用实例

from concurrent import futures
import time
​
​
def test(num):
    return time.ctime(), num
​
​
data = range(10)
with futures.ThreadPoolExecutor(max_workers=3) as executor:
    for future in executor.map(test, data):
        print(future)

result:

('Sun Jan 16 12:31:12 2022', 0)
('Sun Jan 16 12:31:12 2022', 1)
('Sun Jan 16 12:31:12 2022', 2)
('Sun Jan 16 12:31:12 2022', 3)
('Sun Jan 16 12:31:12 2022', 4)
('Sun Jan 16 12:31:12 2022', 5)
('Sun Jan 16 12:31:12 2022', 6)
('Sun Jan 16 12:31:12 2022', 7)
('Sun Jan 16 12:31:12 2022', 8)
('Sun Jan 16 12:31:12 2022', 9)

5 shutdown()方法

释放系统资源,在submit()方法或者map()方法之后调用,使用with语句可以显示避免调用此方法。 Executor.shutdown(wait=True)