ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

queue/生产者消费者(了解)

2021-07-21 22:05:06  阅读:143  来源: 互联网

标签:__ Queue 消费者 get 生产者 queue print Process put


1.queue队列

#Queue([maxsize]):创建共享的进程队列。
maxsize是队列中允许的最大项数。
如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中。


Queue的实例q具有以下方法:

# q.get( [ block [ ,timeout ] ] ):
返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。
block用于控制阻塞行为,默认为True. 
如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。
timeout是可选超时时间,用在阻塞模式中。
如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。

# q.get_nowait() :同q.get(False)方法。

# q.put(item [, block [,timeout ] ] ) :
将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。
block控制阻塞行为,默认为True。
如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。
timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。

# q.qsize() :
返回队列中目前项目的正确数量。
此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。
在某些系统上,此方法可能引发NotImplementedError异常。

# q.empty() :
如果调用此方法时 q为空,返回True。
如果其他进程或线程正在往队列中添加项目,结果是不可靠的。
也就是说,在返回和使用结果之间,队列中可能已经加入新的项目。

# q.full() :
如果q已满,返回为True. 由于线程的存在,结果也可能是不可靠的(参考q.empty()方法)。

代码示例:
from  multiprocessing import  Queue

if __name__ == '__main__':

    q = Queue(3)

    q.put('ly is dsb1')
    q.put('ly is dsb2')
    # q.put('ly is dsb3')
    # q.put('ly is dsb2')
    # q.put('ly is dsb3')
    # q.put('ly is dsb4',block=False)
    # q.put('ly is dsb4',timeout=1)      # 给一秒的时间,一秒内还不传,就报错
    # q.put_nowait('ly is dsb4')         # 直接报错


    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())

    # q.get_nowait()
    # print(q.qsize())    #判断队列里有几个值
    # print(q.empty())    #满了以后返回一个F
    print(q.full())


利用Queue解决进程间数据隔离

from multiprocessing import Queue, Process
import os, time


def task(queue):
    print("这个进程id:%s开始放数据了" % os.getpid())
    time.sleep(2)
    queue.put('ly is dsb')
    print("这个进程id:%s数据放完了" % os.getpid())


if __name__ == '__main__':
    q = Queue(3)
    p = Process(target=task, args=(q,))
    p.start()

    print("主进程")

    res = q.get()
    print("主进程中取值:",res)

多进程放入数据到Queue

from multiprocessing import Queue, Process
import os, time


def get_task(queue):
    print("%s:%s" % (os.getpid(), queue.get()))

def put_task(queue):
    queue.put("%s开始写数据了" % os.getpid())


if __name__ == '__main__':
    q = Queue(3)

    p = Process(target=put_task, args=(q,))
    p.start()

    p1 = Process(target=put_task, args=(q,))
    p1.start()

    p2 = Process(target=get_task, args=(q,))
    p2.start()

    p3 = Process(target=get_task, args=(q,))
    p3.start()

2.生产者消费者代码演示

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

def producer(queue, food):
    # 把数据全部放在Queue
    for i in range(10):
        data = "这个进程id:%s, 生产了%s个%s" % (os.getpid(), i, food)
        print(data)

        time.sleep(random.randint(1, 3))
        # 放入数据
        queue.put("第%s个%s" % (i, food))

def consumer(queue, name):
    while True:
        try:
            res = queue.get(timeout=5)
            if not res:break
            data = "这个消费者:%s, 吃了%s" % (name, res)
            print(data)
        except Exception as e:
            print(e)
            break

if __name__ == '__main__':
    q = Queue(3)
    p1 = Process(target=producer, args=(q, '面包'))
    p2 = Process(target=producer, args=(q, '奶粉'))
    p3 = Process(target=producer, args=(q, '冰淇淋'))
    p1.start()
    p2.start()
    p3.start()

    p4 = Process(target=consumer, args=(q, '许鹏'))
    p5 = Process(target=consumer, args=(q, '勇哥'))
    p6 = Process(target=consumer, args=(q, '勇哥2'))
    p7 = Process(target=consumer, args=(q, '勇哥3'))
    p4.start()
    p5.start()
    p6.start()
    p7.start()

    # time.sleep(1000)
    # none放在这里是不行的,原因是主进程直接执行了put none, 消费者直接获取到None, 程序直接结束了
    # p.join()
    # q.put(None)
    p1.join()
    p2.join()
    p3.join()

    q.put(None)
    q.put(None)
    q.put(None)


标签:__,Queue,消费者,get,生产者,queue,print,Process,put
来源: https://www.cnblogs.com/lyz666/p/15041764.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有