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)