zoukankan      html  css  js  c++  java
  • 进程间通信 基于队列实现进程与进程间通信 生产者消费者模型

    队列:先进先出

    堆栈:先进后出

    利用队列实现进程通信

    from multiprocessing import Queue
    q =Queue(5) #产生一个最多能够存放5个数据的队列 如果不写 默认就存放很多份
    
    # q.put(1)    #往队列中存放数据,如果存放的数据个数大于队列最大存储个数,程序会阻塞
    # q.put(2)
    # q.put(3)
    # q.put(4)
    # print(q.full()) # False判断队列是否被存放满
    # q.put(5)
    # print(q.full())     #True
    # q.put(6)
    # print(q.full())
    #
    
    for i in  range(1,6):
        q.put(i)    #for循环往队列里面存放数据
    
    # print(q.get())  #1  取数据,get一次就取一个
    # print(q.get())  #2
    # print(q.get())  #3
    # print(q.empty())    #False
    # q.get_nowait()      # 下面 4 就被这个获取了 不会显示 在队列有数据的情况下,跟get取值一样,当队列没有数据的情况下,取值直接报错
    # print(q.get())  #4
    # print(q.get())  #5
    # print(q.empty())     #True 判断队列是否为空,需要注意的是,在并发的情况下,这个方法判断不准确
    
    # print(q.get())  #如果队列为空,get会在原地等待队列中有数据过来
    # print(q.get())  #如果队列为空,get会在原地等待队列中有数据过来
    
    print(q.get())  #1
    print(q.get())  #2
    print(q.get())  #3
    q.get_nowait()  #4 不显示
    print(q.empty())    #False 没有被取完
    print(q.get())      #5
    print(q.empty())    #True
    q.get_nowait()      #没有值的话 会报错

    基于队列实现进程与进程间通信

    from multiprocessing import Queue,Process
    
    def producer(q):
        q.put('hello baby!')
    
    def consumer(q):
        print(q.get())
    
    if __name__ == '__main__':
        q = Queue()   #生成一个队列对象
        p1 = Process(target=producer,args=(q,))     #子进程
        p2 = Process(target=consumer,args=(q,))     #子进程
        p1.start()
        p2.start()
        
    hello baby!

    生产者消费者模型

    生产者消费者模型:

      生产者:做包子  生产数据的

      消费者:买包子的  处理数据的

      两者之间的通信介质:队列/管道

      解决供需不平衡的问题

        定义一个队列,用来存放固定数量的数据

        解决一个生产者和消费者不需要直接打交道,两者都通过队列实现数据传输

      Queue:管道+锁

    from multiprocessing import Queue, Process
                                # 队列  #创建进程
    import time
    import random
    
    
    def producer(name, food, q):
        for i in range(1, 5):
            data = '%s生产的%s个%s' % (name, i, food)
            time.sleep(random.randint(1, 2))
            print(data)
            q.put(data)                 # 将生产的数据放入队列中
    
    
    def consumer(name, q):
        while True:
            data = q.get()              #从队列里取数据
            if data is None: break      #队列里没有值的时候结束子进程
            time.sleep(random.randint(1, 2))
            print('%s吃了%s' % (name, data))
    
    
    if __name__ == '__main__':
        q = Queue()  # 生产一个队列对象
        p1 = Process(target=producer, args=('大厨', '包子', q))
        c1 = Process(target=consumer, args=('食客', q))
        p1.start()
        c1.start()
        p1.join()                   #先让生产者结束后再执行下面的主进程的diamante
    
        print('主进程')              # 主进程运行完后不会立刻结束  会等待子进程运行结束来回收子进程资源
        
        
    #其中的一次结果:
        大厨生产的1个包子
        大厨生产的2个包子
        食客吃了大厨生产的1个包子
        食客吃了大厨生产的2个包子
        大厨生产的3个包子
        大厨生产的4个包子
        主进程
        食客吃了大厨生产的3个包子
        食客吃了大厨生产的4个包子
    from multiprocessing import Process, JoinableQueue
                                #创建进程      等待队列结束
    import time
    import random
    
    def producer(name,food,q):
        for i in range(1,5):
            data='%s:生产的第:%s个:%s'%(name,i,food)
            time.sleep(random.randint(1,2))
            print(data)
            q.put(data)     #将生产的数据放入队列中
    
    
    def consumer(name,q):
        while True:
            data=q.get()
            if data is None:break
            time.sleep(random.randint(1,2))
            print('%s吃了 %s'%(name,data))
            q.task_done()   #告诉你的队列,你已经将数据取出并且处理完毕
    
    if __name__ == '__main__':
        q=JoinableQueue()   #创建一个队列对象
        p1=Process(target=producer,args=('厨子','蒸饺',q))
        c1=Process(target=consumer,args=('吃货',q))
        p1.start()
        c1.daemon=True  #守护进程 主进程结束 立即让子进程结束
        c1.start()
        p1.join()   #等待生产者生产完所有的数据
    
        #在生产者生产完数据之后,往队列里面放一个提示性的消息,告诉消费者已经没有了,你走吧。不要等了
        # q.put(None)
    
        q.join()     #等待队列中数据全部取出
        print('')
    
    
    """
    阻塞1:主进程等待生产者进程结束 生产者进程时间 消费者同时也在消费
    
    阻塞2:队列数据必须取完才执行下面的主进程的下面代码
    
    厨子:生产的第:1个:蒸饺
    厨子:生产的第:2个:蒸饺
    厨子:生产的第:3个:蒸饺
    吃货吃了 厨子:生产的第:1个:蒸饺
    厨子:生产的第:4个:蒸饺
    吃货吃了 厨子:生产的第:2个:蒸饺
    吃货吃了 厨子:生产的第:3个:蒸饺
    吃货吃了 厨子:生产的第:4个:蒸饺
    主
    """
  • 相关阅读:
    Web前端浏览器兼容性问题及解决方案
    JS
    vue element-ui 重置样式问题
    学习的一些文章链接
    打开新世界的第一步:学习servlet
    java学习初体验之课后习题
    下载、安装jdk8(Windows下)并配置变量环境
    下载PhpStorm并进行激活
    WCF+NHibernate 序列化
    wcf 证书+ssl+自定义用户名密码
  • 原文地址:https://www.cnblogs.com/lakei/p/10827290.html
Copyright © 2011-2022 走看看