python 构造生产者消费者模型

python 构造生产者消费者模型

生产者消费者模型 的建立需要借助第三方进行传递信息。那么使用什么充当这个第三方进行传递信息能够使得生产者消费者模型能够效率更高,实现更为简单呢?

这里使用队列作为这个第三方进行传递信息,连同生产者与消费者。(队列:管道+锁),既能够传递信息,同时也能够保证数据安全。

普通版

import time
import random
from multiprocessing import Process,Queue

""" 生产者消费者初级模型 """

def producer(name,food,q):
    for i in range(5):
        data = "{}生产了{}{}".format(name,food,i)      # 生产者生产食品
        time.sleep(random.randint(1,3))          # 模拟网络或者其他的延迟,没有什么是处于完全理想状态
        print(data)
        q.put(data)


def consumer(name,q):
    while True:
        food = q.get()          # 从队列中取出数据
        # 判断队列中数据是否已经取出完毕,需要提前在队列中插入表示数据
        if food is None: break
        time.sleep(random.randint(1,3))  # 模拟时间延迟(网络延迟)
        print("{}处理掉了{}".format(name,food))


if __name__ == '__main__':
    q = Queue()
    p1 = Process(target=producer, args=("生产者1", '寿司', q))
    p2 = Process(target=producer, args=("生产者2", '寿司', q))
    c1 = Process(target=consumer, args=("消费者1", q))
    c2 = Process(target=consumer, args=("消费者2", q))
    p1.start()
    p2.start()
    c1.start()
    c2.start()

    # 等待进程运行结束之后,在队列中插入标识生产结束
    p1.join()
    p2.join()
    # 插入的标识的数量需要根据消费者数量进行确定
    q.put(None)
    q.put(None)

这是直接使用多进程里面的模块队列进行传递信息,使得生产者与消费者进行连同,但是这个模型存在一个缺点,那就需要为队列插入特定的结束标识,同时需要确定消费者的数量,插入对应数量的结束标识,同时也需要等待生产者进程运行结束,之后才能插入标识数据,不然会导致进程提前中止。

进阶版

import time
import random
from multiprocessing import Process,Queue,JoinableQueue

""" 生产者消费者进阶模型 """

def producer(name,food,q):
    for i in range(5):
        data = "{}生产了{}{}".format(name,food,i)      # 生产者生产食品
        time.sleep(random.randint(1,3))          # 模拟网络或者其他的延迟,没有什么是处于完全理想状态
        print(data)
        q.put(data)


def consumer(name,q):
    while True:
        food = q.get()          # 从队列中取出数据
        time.sleep(random.randint(1,3))  # 模拟时间延迟(网络延迟)
        print("{}处理掉了{}".format(name,food))
        q.task_done()        # 对队列中的数据的计数减一


if __name__ == '__main__':
    q = JoinableQueue()
    p1 = Process(target=producer, args=("生产者1", '寿司', q))
    p2 = Process(target=producer, args=("生产者2", '寿司', q))
    c1 = Process(target=consumer, args=("消费者1", q))
    c2 = Process(target=consumer, args=("消费者2", q))
    p1.start()
    p2.start()
    # 因为当数据被取出完全的时候,消费者还会在等待取数据,这时候需要守护进程的出现
    c1.daemon = True
    c2.daemon = True
    c1.start()
    c2.start()

    q.join()        # 等待队列中的数据被取出完全

    """ JoinableQueue 这个队列的机制与python的垃圾回收机制中的引用计数相类似 当往队列中插入一个数据时候,计数自动加一, 当调用.task_done()方法使用,对队列的计算进行减一操作; .join()方法与进程中的一样都是阻塞等待,等待队列中的计算清零,才继续运行 """

这样子不但解决了需要设置结束标志,同时也解决了消费者数量的问题。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115133.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一个人决定离职的征兆有哪些?「建议收藏」

    一个人决定离职的征兆有哪些?

    2022年2月18日
    117
  • js获取ModelAndView值的问题[通俗易懂]

    js获取ModelAndView值的问题[通俗易懂]JS当中不能接收ModelAndView的返回值吗?一定要在JSP页面中才能接收吗?1方法一【有效】可以的,跟el表达式访问方式一样。示例代码,一个数据展示请求的Action中存入一个userId:@RequestMapping(value=”/diary”)publicModelAndViewtoDiaryList(HttpSessionsession)

    2022年7月18日
    14
  • C#中write和writeline的区别「建议收藏」

    writeLine:将要输出的字符串与换行控制字符一起输出,当次语句执行完毕时候,光标会移到目前输出字符串的下一行。例如:write:光标会停在输出字符串的最后一个字符,不会移动到下一行。writeLine实例运行效果如下图:write实例运行效果如下图:…

    2022年4月10日
    38
  • think in java一_Think in Java(一):Java基础「建议收藏」

    think in java一_Think in Java(一):Java基础「建议收藏」一.OOP的特点(1)万物皆为对象;(2)程序是对象的集合,他们通过发送信息来告诉彼此所要做的;(3)每个对象都有自己的由其他对象所构成的存储;(4)每个对象都拥有它的类型;(5)某一特定类型的对象都可以接收同样的消息;二.Java比C++简单?(1)Java有垃圾回收器,不用手动销毁对象;(2)Java使用单根继承;(3)Java只能以一种方式创建对象(在堆上创建);三….

    2022年7月8日
    23
  • 2020考研,老学长帮你规划[通俗易懂]

    2020考研,老学长帮你规划[通俗易懂]高能干货预警,文章目前已经近三万字,这可能是最负责的一篇文章了。文章很长,建议拿好笔记慢慢看。本文会解决你在考研各科在不同时期不同阶段遇到的所有问题,方法具体到草稿纸怎么使用,课本具体怎么使用,相信我,读完你一定会有巨大收获。我总结了我一年以来遇到的所有问题,使用的所有方法。既然最终目的是在考研这场「考试」中获得高分,那么所有的时间和精力,都应该围绕着「考试」进行,才是效率最高的方式。但是…

    2022年9月24日
    2
  • Java设计模式(五)之创建型模式:原型模式

    Java设计模式(五)之创建型模式:原型模式

    2021年4月8日
    125

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号