由于GIL的存在,Python中的多线程其实并不是真正意义上的多线程,在之前的一篇文章Python中的多线程与多进程那些事 中提到I/O密集型可使用多线程并发执行提高效率、而计算密集型需使用多进程并行执行提高效率。
针对计算密集型的任务,我们如何通过多进程提高效率?
multiprocessing & Queue 实现分布式计算
本文将介绍如何通过multiprocessing.BaseManager、Queue模块实现简易的分布式计算框架。
主节点负责任务的派发和任务结果的采集,从节点可以是在同一电脑/服务器的不同进程,或者其他电脑/服务器上,负责任务执行和结果上报。主节点与从节点通过Queue队列实现数据共享(任务下发、结果反馈)。
整体设计主要分为Task、MasterWork、SlaveWork三个模块,接下来分享一下主要设计及源码。
Task模块
任务模块,根据任务需求将我们的任务单独封装在Task.py模块中,如下:
MasterWork(主节点/服务节点)
负责任务派发和结果采集,主从节点通过Queue实现任务、结果共享。流程如下:
- 创建发送任务、接收结果的Queue消息队列。
- 将两个队列注册到网络上。
- 设置主节点队列IP、端口、密钥,开启服务。
- 通过网络访问Queue对象。
- 开启主节点,向从节点分发任务,等待从节点接受。
- 从节点消费发送的任务队列,待任务分发结束,获取任务结果。
SlaveWork(从节点/计算节点)
负责任务执行和结果反馈,主从节点通过Queue实现任务、结果共享。处理流程如下:
- 通过IP、端口号和密钥连接主节点。
- 获取发送任务、接收结果的队列。
- 消费队列执行任务。
- 将执行结果提交接收结果的队列。
代码应用演示
在Task.py 添加任务函数。
调整主从节点任务派发具体函数、次数或参数。
一般情况分发次数等于任务数,即分发任务的参数。
启动主节点
启动从节点
将从节点计算模块SlaveWork1.py 发送至各计算节点,启动从节点即实现分布式计算,即N个从节点消费服务节点分发任务,并返回任务执行状态、结果。
启动从节点后,可以在主节点运行界面,看到各节点的任务完成情况。
日拱一卒,相关阅读: