版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32502511/article/details/84553079
在python开发中,有时候会有这样的需求,比如说我后很多个任务,需要并行执行,也就是说有一个任务队列,大家都知道,在python中的多线程,它其实从严格意义上来讲,并不是真正的多线程。所以用多线程我们还不如使用多进程。使用多进程的有什么好处了,它可以实现分布式多机并行。多个客户端共享一个任务队列。可以大大提高任务执行效率,下面我我将使用python中的multiprocessing库实现一个多进程分布式的任务示例:
假使我们使用data_test=[{"name":"张三"},{"name":"李四"},{"name":"王五"},{"name":"麻子"},{"name":"如花"},{"name":"西施"}] 这个来表示有很多个任务需要处理
新建一个master.py文件,这个文件表示主键类,用于派发任务,里面代码如下:
from multiprocessing.managers import BaseManager
from multiprocessing import Queue
import time
#主机管理类,用于任务派发
class Master:
def __init__(self):
# 派发出去的任务队列
self.dispatched_task_queue = Queue()
# 完成的任务队列
self.finished_task_queue = Queue()
def get_dispatched_task_queue(self):
return self.dispatched_task_queue
def get_finished_task_queue(self):
return self.finished_task_queue
#开始任务
def start(self):
# 把派发作业队列和完成作业队列注册到网络上
BaseManager.register('get_dispatched_task_queue', callable=self.get_dispatched_task_queue)
BaseManager.register('get_finished_task_queue', callable=self.get_finished_task_queue)
# 监听端口和启动服务,authkey为验证码,自己随便取的,address改成自己的ip
manager = BaseManager(address=('192.168.10.149', 8888), authkey='taimei'.encode("utf-8"))
manager.start()
# 使用上面注册的方法获取队列
dispatched_tasks = manager.get_dispatched_task_queue() #获取派发队列
finished_tasks = manager.get_finished_task_queue() #获取返回队列
while True:
data_test=[{"name":"张三"},{"name":"李四"},{"name":"王五"},{"name":"麻子"},{"name":"如花"},{"name":"西施"}]
for index,item in enumerate(data_test):
dispatched_tasks.put(item)
print("派发任务: "+str(index))
#监听返回结果
while not dispatched_tasks.empty():
result = finished_tasks.get()
print("-------返回数据----------")
print(result)
#暂停10秒后继续进行下一轮的任务派发
time.sleep(10)
manager.shutdown()
if __name__ == "__main__":
master = Master()
master.start()
然后我们再创建一个slave.py文件,这个文件表示子节点,也就是执行任务的主机,可以有一个或者多个,理论上可以无限增多。代码如下:
import time
from multiprocessing import Queue
from multiprocessing.managers import BaseManager
#从机类
class Slave:
def __init__(self):
# 派发出去的任务队列
self.dispatched_task_queue = Queue()
# 完成的任务队列
self.finished_task_queue = Queue()
def start(self):
# 把派发任务队列和完成任务队列注册到网络上
BaseManager.register('get_dispatched_task_queue')
BaseManager.register('get_finished_task_queue')
# 连接master
server = '192.168.10.149'
print('连接主机服务器 %s...' % server)
manager = BaseManager(address=(server,8888), authkey='taimei'.encode("utf-8"))
manager.connect()
# 使用上面注册的方法获取队列
dispatched_tasks = manager.get_dispatched_task_queue()
finished_tasks = manager.get_finished_task_queue()
# 运行作业并返回结果,这里只是模拟作业运行,所以返回的是接收到的作业
while True:
try:
task = dispatched_tasks.get(timeout=1)
print("正在执行任务..."+str(task))
#这里省略掉处理任务的过程
time.sleep(1)
finished_tasks.put(task["name"]+" 任务已经执行完毕!")
except Exception:
continue
if __name__ == "__main__":
slave = Slave()
slave.start()
测试:
首先执行master.py派发任务,如下图
可以看到,它已经派发了5个任务,然后我再运行slave.py去从队列中获取任务,运行如图:
再次切换到master面板,如图:
可以看到,它已经接受到了slave执行完后的结果。这个slave可以复制很多份到不同的主机上去同时运行,它们都会共享一个队列,从master中获取任务执行。
关于代码的意思,里面的注释已经写得很清楚啦,看不懂的地方可以左边进群问我哟!