我是靠谱客的博主 负责短靴,最近开发中收集的这篇文章主要介绍python学习笔记-生产者消费者模型及代码实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本文为了说明例子,用中文作为变量写在了程序里面,一般编程最好不要那么写
生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。

这里实现如下情况的生产–消费模型:

生产者不断交替地生产两组数据“姓名–1 --> 内容–1”,“姓名–2--> 内容–2”,消费者不断交替地取得这两组数据,这里的“姓名–1”和“姓名–2”模拟为数据的名称,“内容–1 ”和“内容–2 ”模拟为数据的内容。

由于本程序中牵扯到线程运行的不确定性,因此可能会出现以下问题:

假设生产者线程刚向数据存储空间添加了数据的名称,还没有加入该信息的内容,程序就切换到了消费者线程,消费者线程将把信息的名称和上一个信息的内容联系在一起;
生产者生产了若干次数据,消费者才开始取数据,或者是,消费者取完一次数据后,还没等生产者放入新的数据,又重复取出了已取过的数据。
问题 1 很明显要靠同步来解决,问题 2 则需要线程间通信,生产者线程放入数据后,通知消费者线程取出数据,消费者线程取出数据后,通知生产者线程生产数据,这里用 wait/notify 机制来实现。

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


def 生产者(name,food,q):
    for i in range(5):
        data = '%s生产了%s%s'%(name,food,i)
        # 模拟延迟
        time.sleep(random.randint(1,3))
        print(data)
        # 将数据放入 队列中
        q.put(data)


def 消费者(name,q):
    
    while True:
        food = q.get()  # 没有数据就会卡住
        # 判断当前是否有结束的标识
        # if food is None:break
        time.sleep(random.randint(1,3))#每个人的手速不同
        print('%s吃了%s'%(name,food))
        A.task_done()  # 告诉队列你已经从里面取出了一个数据并且处理完毕了


if __name__ == '__main__':
    A = Queue()
    A = JoinableQueue()
    B1 = Process(target=生产者,args=('厨师A','包子',A))
    B2 = Process(target=生产者,args=('厨师B','油条',A))
    C1 = Process(target=消费者,args=('客人A',A))
    C2 = Process(target=消费者,args=('客人B',A))
    B1.start()
    B2.start()
    # 将消费者设置成守护进程
    C1.daemon = True
    C2.daemon = True
    C1.start()
    C2.start()
    B1.join()
    B2.join()
    # 等待生产者生产完毕之后 往队列中添加特定的结束符号
    A.put(None)  # 肯定在所有生产者生产的数据的末尾
    A.put(None)  # 肯定在所有生产者生产的数据的末尾
    A.join()  # 等待队列中所有的数据被取完再执行往下执行代码

    #JoinableQueue 每当你往该队列中存入数据的时候 内部会有一个计数器+1
    #没当你调用task_done的时候 计数器-1
    #A.join() 当计数器为0的时候 才往后运行

    # 只要A.join执行完毕 说明消费者已经处理完数据了  消费者就没有存在的必要了

最后

以上就是负责短靴为你收集整理的python学习笔记-生产者消费者模型及代码实现的全部内容,希望文章能够帮你解决python学习笔记-生产者消费者模型及代码实现所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部