接上文Python开发从零开始-47.2-多进程和多线程,本文小编与大家分享 Python 多进程和多线程的相关知识。
(3)创建进程池
进程池是一种创建和管理进程的技术,它可以有效地控制同时运行的进程数量,从而提高程序的效率和性能。进程池的核心思想是预先创建一定数量的进程,并将这些进程放入一个池中。当有新的任务到来时,进程池会分配一个空闲的进程来处理这个任务。任务完成后,进程不会关闭,而是返回池中等待下一个任务。这种方式避免了频繁创建和销毁进程的开销,同时也限制了同时运行的进程数量,防止操作系统过载。
可以通过 multiprocessing.Pool 对象来创建一个进程池。创建 Pool 对象时,可以指定进程池中进程的数量。如果不指定,默认使用 CPU 的核心数。
Pool 对象的常用方法包括:
apply(): 同步执行一个任务,直到得到结果。该方法会阻塞主进程,直到任务执行完毕;
apply_async():异步执行一个任务,返回一个 AsyncResult 对象,可以用来获取任务结果。方法是非阻塞的;
map():用于将一个可迭代对象中的每个元素应用到指定的函数上,并返回一个包含所有结果的列表。该方法会阻塞主进程;
map_async():方法是非阻塞的,它会立即返回一个 AsyncResult 对象,通过该对象可以在任务执行完毕后获取结果;
close():关闭进程池,不再接受新的任务;
join():等待所有进程池中的进程执行完毕。
【小编提示】 multiprocessing.pool.Pool 对象在使用中,常见的错误是调用 close() 方法之后,却忘记或错误地调用 join() 方法。为了避免该问题,最推荐的方法是使用 Pool 对象的上下文管理器 (with 语句)。 当使用 with 语句时,Python 会自动在块退出时执行以下操作:
|
Pool 对象使用代码示例如下:
import multiprocessingdef worker(num):"""线程工作函数"""print(f"线程: {num} 执行中...")return num * numif __name__ == '__main__':# 创建进程池,指定进程数with multiprocessing.Pool(processes=4) as pool:print("线程池已创建:")# 分配任务到进程池,并收集结果result = pool.map(worker, range(4))print("线程池已关闭,执行结果为:", result)
代码运行输出如下:
>>> %Run process_3.py线程池已创建:线程: 0 执行中...线程: 1 执行中...线程: 2 执行中...线程: 3 执行中...线程池已关闭,执行结果为: [0, 1, 4, 9]>>>
(4)进程间通信
multiprocessing 模块中,进程间的通信可以通过多种方式实现,包括使用队列(Queue)、管道(Pipe)、共享内存(Value、Array)、事件(Event)和锁(Lock)。下面主要介绍 Queue 和 Pipe 使用方法。
1)使用 Queue 进行进程间通信
队列是进程间通信的一种常见方式,它允许数据从一个进程传递到另一个进程。可以使用 multiprocessing.Queue 对象来创建一个队列,其常用方法包括:
Queue():Queue 对象的构造方法,返回一个队列对象;
put():将对象放入队列;使用 put(None) 作为结束信号是一种常见的做法,特别是在信息生产者结束后通知信息消费者停止等待新数据。这有助于优雅地关闭进程;
get():从队列中取出对象。
Queue 对象的使用示例如下:
import multiprocessingdef worker(q):q.put("这是进程间传递的信息")if __name__ == '__main__':# 创建信息队列对象queue = multiprocessing.Queue()process = multiprocessing.Process(target=worker, args=(queue,))process.start()process.join()# 输出进程间传递的信息print(queue.get())
程序运行输出:
>>> %Run process_5.py这是进程间传递的信息>>>
受文章篇幅所限,下文将继续介绍 Python 多进程和多线程的相关知识。