Python并发编程:从多进程到AsyncIO
1. 多进程的问题
多进程编程存在一些问题,在Python中,没有一种通用的最佳并发解决方案,需要根据具体的并行问题来选择合适的方法,有时甚至没有最佳方案。
多进程的主要缺点如下:
- 数据共享成本高 :进程间的所有通信,如通过队列、管道或更隐式的机制,都需要对对象进行序列化(pickling)。过度的序列化会迅速占据处理时间。多进程在进程间传递相对较小的对象,且每个对象需要大量处理时效果最佳。如果进程间不需要通信,使用多进程模块可能就没有意义,可以启动四个独立的Python进程并独立使用它们。
- 变量访问混乱 :和线程一样,很难确定变量或方法是在哪个进程中被访问的。在多进程中,如果从另一个进程访问变量,通常会覆盖当前运行进程中的变量,而另一个进程保留旧值,这会给代码维护带来很大困扰。
2. Futures
Futures是一种更异步的并发方式,它根据需要的并发类型(倾向于I/O还是CPU)包装多进程或线程。虽然它不能完全解决意外改变共享状态的问题,但可以让我们更方便地跟踪代码。Futures为不同的线程或进程提供了明确的边界,类似于多进程池,适用于“调用 - 响应”类型的交互,处理可以在另一个线程中进行,在未来的某个时间可以获取结果。
一个Future对象基本上包装了一个函数调用,该函数调用在后台的线程或进程中运行。Future对象有方法来检查调用是否完成,并在完成后获取结果。
以下是一个使用 ThreadPoolExecutor
进行文件搜