python3实现多进程并发任务

版权声明:本文为博主原创文章,未经博主允许不得转载。 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中获取任务执行。

关于代码的意思,里面的注释已经写得很清楚啦,看不懂的地方可以左边进群问我哟!

猜你喜欢

转载自blog.csdn.net/qq_32502511/article/details/84553079