zoukankan      html  css  js  c++  java
  • python-44-初识队列

    前言 

    队列:先进先出,在多线程里面使用,队列内置有锁线程安全的数据结构,不用关心数据怎么放的,只要知道怎么用就可以,怎么插数据拿数据。

    什么是生产者/消费者模型?为什么会出现生产者/消费者膨胀问题?
    ①比如生产者在生产,生产的货物积囤有限,那么可以一边卖给消费者,一边生产。
    ②但是这样子会导致任意一方可能出现 供过于求或供不应求,所以要平衡。

    一、队列

    队列的及格方法:

    • q.put():存,当队列满的时候阻塞等待队列有空位置
    • q.full():查看队列是否满了,不完全准确
    • q.get():取,当队列空的时候阻塞等待队列有数据
    • q.empty():判断队列是否为空
    • join():阻塞进程
    • task_done():检测任务完成

    1、初识队列。

    import time
    from multiprocessing import Queue
    q=Queue(3)              # 设置3个,没设置即为不上限
    q.put(1)
    q.put(2)
    q.put(3)
    print(q.full())         # 查看队列是否满了
    print(q.get())          # 取走队列的对象
    print(q.get())          # 取走队列的对象
    print(q.get())          # 取走队列的对象
    print(q.empty())        # 判断队列是否为空
    # print(q.get_nowait())   # 如果为空,抛异常queue.Empty
    while 1:
        try:q.get_nowait()
        except:
            print('队列为空!!!')
            time.sleep(1)

     2、队列在进程中使用。

    # 2、队列在进程中使用
    from multiprocessing import Process,Queue
    def func(q):
        q.put('给我一个吻,可以不可以?')
    def give(q):
        q.get()
    if __name__ == '__main__':
        q=Queue()
        p=Process(target=func,args=(q,))
        p1=Process(target=give,args=(q,))
        p.start()
        p1.start()
        print(q.get())

    二、生产者/消费者问题解决办法

    1、Queue,第一种解决:生产者/消费者膨胀问题。

    基本思路:①队列实现,消费者一直获取值,直到获取到None就意味着队列没有值。

    但是有个不好之处,消费者不知道生产者的产量,直到取到None。

    # 1、Queue,第一种解决:生产者/消费者膨胀问题。
    import time
    import random
    from multiprocessing import Process,Queue
    def consumer(q,name):
        while 1:
            mask = q.get()
            if mask is None:
                print('%s口罩空'%name)
                break
            print('%s使用了 %s' % (name,mask))
            time.sleep(random.randint(1,3))
    
    def producer(name,mask,q):
        for i in range(1,5):
            time.sleep(random.randint(1,3))
            m = '%s生产了%s %s'%(name,mask,i)
            print(m)
            q.put(m)
    
    if __name__  == '__main__':
        q = Queue()
        p1 = Process(target=producer,args=('大厂','N95口罩',q))
        p2 = Process(target=producer, args=('小厂','N90口罩', q))
        c1 = Process(target=consumer, args=(q,'A企业'))
        c2 = Process(target=consumer, args=(q,'B企业'))
        p1.start()
        p2.start()
        c1.start()
        c2.start()
        p1.join()
        p2.join()
        q.put(None)
        q.put(None)

    2、JoinableQueue,第二种解决:生产者/消费者膨胀问题。

    基本思路:
    ①消费者 中把所有的任务执行完;
    ②生产者 中的p.join()感知到消费者任务执行完就停止阻塞;
    ③生产者停止堵塞后意味着 生产者 的所有进程结束;
    主进程中的p.join()结束
    主进程中代码结束
    守护进程(消费者的进程)结束

    # 2、JoinableQueue,第二种解决:生产者/消费者膨胀问题。
    import time
    import random
    from multiprocessing import Process,JoinableQueue
    def consumer(q,name):
        while 1:
            mask = q.get()
            if mask is None:
                print('%s口罩空'%name)
                break
            print('%s使用了 %s' % (name,mask))
            time.sleep(random.randint(1,3))
            q.task_done()                      # 类似监控生产的数量,计数器每次-1
    
    def producer(name,mask,q):
        for i in range(1,5):
            time.sleep(random.randint(1,3))
            m = '%s生产了%s %s'%(name,mask,i)
            print(m)
            q.put(m)
        q.join()                             # 堵塞,等到队列中的所有数据全部都被消费者执行完
    
    if __name__  == '__main__':
        q = JoinableQueue()
        p1 = Process(target=producer,args=('大厂','N95口罩',q))
        p2 = Process(target=producer, args=('小厂','N90口罩', q))
        c1 = Process(target=consumer, args=(q,'A企业'))
        c2 = Process(target=consumer, args=(q,'B企业'))
        p1.start()
        p2.start()
        c1.daemon=True      # 设为守护进程,既是主进程的代码执行完后子进程自动结束
        c2.daemon=True      # 设为守护进程,既是主进程的代码执行完后子进程自动结束
        c1.start()
        c2.start()
        p1.join()
        p2.join()

    欢迎来大家QQ交流群一起学习:482713805

  • 相关阅读:
    自动对一个文件夹下的N个word文件批量执行一个宏
    PHP正则匹配联系方式手机号、QQ、微信、邮箱、固定电话
    私信基本功能数据库设计
    ArcGIS三分式标注、四分式标注和同时上下标实现
    Word2019文档中将页面边框更改为文本边框的方法
    Arcgis彻底删除和卸载
    ArcMap中各种基本概念的介绍
    ArcGIS Python工具箱.pyt裁剪工具
    C# Object对象的ToString方法在转换日期时丢失毫秒
    2020年糖尿病领域中国学者学术影响力排名
  • 原文地址:https://www.cnblogs.com/gsxl/p/12586702.html
Copyright © 2011-2022 走看看