一、基本介绍
concurrent.futures 模块是 Python3.2 中引入的新模块,用于支持异步执行,以及在多核CPU和网络I/O中进行高效的并发编程。这个模块提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,简化了跨平台异步编程的实现。
首先,让我们先来理解两种并发编程的方式:
1、多进程
当通过多进程来实现并发编程时,程序会将任务分配给多个进程,这些进程可以在不同的CPU上同时运行。进程之间是独立的,各自有自己的内存空间等,可以实现真正的并行执行。不过,进程之间的通信比较耗时,需要使用IPC(进程间通信)机制,而且进程之间的切换比线程之间的切换耗时,所以创建进程的代价较高。
2、多线程
当通过多线程来实现并发编程时,程序会将任务分配给多个线程,这些线程可以在同一个进程中的不同CPU核上同时运行。线程之间共享进程的内存空间,因此开销比较小。但是需要注意,在Python解释器中,线程是无法实现真正的并行执行,因为Python有GIL(全局解释器锁),它确保同时只有一个线程运行Python代码。因此,一个Python进程中的多个线程并不能并行执行,在使用多线程编程时不能完全利用多核CPU。
二、基本步骤
导入 concurrent.futures
模块。
创建一个 ThreadPoolExecutor
实例。
使用 submit
方法提交任务到线程池。
使用 as_completed
或 wait
方法来管理线程池中的任务。
三、简单示例
import concurrent.futures
# 定义一个简单的函数,作为线程池中的任务
def task(n):
print(f"Processing {n}")
return n * n
# 创建一个线程池
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
# 提交任务到线程池
futures = [executor.submit(task, i) for i in range(10)]
# 等待所有任务完成,并获取结果
for future in concurrent.futures.as_completed(futures):
result = future.result()
print(f"Task returned {result}")
在这个例子中,我们定义了一个简单的任务 task
,它接收一个整数 n
并返回它的平方。然后我们创建了一个 ThreadPoolExecutor
实例,指定了最大工作线程数为 5。接着我们提交了 10 个任务到线程池,并使用 as_completed
方法来等待所有任务完成并打印结果。
请注意,ThreadPoolExecutor
适用于 I/O 密集型任务,但对于 CPU 密集型任务,使用 ProcessPoolExecutor
可能更合适。