码迷,mamicode.com
首页 > 其他好文 > 详细

4.3 队列/管道

时间:2019-01-31 01:36:21      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:管道   join   empty   join()   display   tpi   数据   示例   put   

目录

4.3.1 概念

4.3.2 创建/方法

4.3.3 生产者消费者模型

 

 

4.3.1  概念原理

技术分享图片

 

 

4.3.2 创建/方法

技术分享图片

 

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()方法)。。

 

  进程间通讯示例

技术分享图片
import time
from multiprocessing import Process, Queue

def f(q):
    q.put([time.asctime(), hi, hello])  #调用主函数中p进程传递过来的进程参数 put函数为向队列中添加一条数据。

if __name__ == __main__:
    q = Queue() #创建一个Queue对象
    p = Process(target=f, args=(q,)) #创建一个进程
    p.start()
    print(q.get())  # [‘Wed Jan 30 23:54:47 2019‘, ‘hi‘, ‘hello‘]
    # 子进程拿到了父进程的数据
    p.join()
View Code

 

 

 

 

4.3.3 生产者消费者模型

 

无信号纯阻塞的模型

技术分享图片
from multiprocessing import Process,Queue
import time,random,os
def consumer(q):
    while True:
        res=q.get()
        time.sleep(random.randint(1,3))
        print(\033[45m%s 吃 %s\033[0m %(os.getpid(),res))

def producer(q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res=包子%s %i
        q.put(res)
        print(\033[44m%s 生产了 %s\033[0m %(os.getpid(),res))

if __name__ == __main__:
    q=Queue()
    #生产者们:即厨师们
    p1=Process(target=producer,args=(q,))

    #消费者们:即吃货们
    c1=Process(target=consumer,args=(q,))

    #开始
    p1.start()
    c1.start()
    print()
View Code

 

 带信号的模型

技术分享图片
from multiprocessing import Process,Queue
import time,random,os
def consumer(q):
    while True:
        res=q.get()
        if res is None:break #收到结束信号则结束
        time.sleep(random.randint(1,3))
        print(\033[45m%s 吃 %s\033[0m %(os.getpid(),res))

def producer(q):
    for i in range(10):
        time.sleep(random.randint(1,3))
        res=包子%s %i
        q.put(res)
        print(\033[44m%s 生产了 %s\033[0m %(os.getpid(),res))
    q.put(None) #发送结束信号
if __name__ == __main__:
    q=Queue()
    #生产者们:即厨师们
    p1=Process(target=producer,args=(q,))

    #消费者们:即吃货们
    c1=Process(target=consumer,args=(q,))

    #开始
    p1.start()
    c1.start()
    print()

 改良版——生产者消费者模型
View Code

 

多消费者时的带信号模型

技术分享图片
from multiprocessing import Process,Queue
import time,random,os
def consumer(q):
    while True:
        res=q.get()
        if res is None:break #收到结束信号则结束
        time.sleep(random.randint(1,3))
        print(\033[45m%s 吃 %s\033[0m %(os.getpid(),res))

def producer(name,q):
    for i in range(2):
        time.sleep(random.randint(1,3))
        res=%s%s %(name,i)
        q.put(res)
        print(\033[44m%s 生产了 %s\033[0m %(os.getpid(),res))

if __name__ == __main__:
    q=Queue()
    #生产者们:即厨师们
    p1=Process(target=producer,args=(包子,q))
    p2=Process(target=producer,args=(骨头,q))
    p3=Process(target=producer,args=(泔水,q))

    #消费者们:即吃货们
    c1=Process(target=consumer,args=(q,))
    c2=Process(target=consumer,args=(q,))

    #开始
    p1.start()
    p2.start()
    p3.start()
    c1.start()

    p1.join() #必须保证生产者全部生产完毕,才应该发送结束信号
    p2.join()
    p3.join()
    q.put(None) #有几个消费者就应该发送几次结束信号None
    q.put(None) #发送结束信号
    print()

 多个消费者的例子:有几个消费者就需要发送几次结束信号
View Code

 

 

4.3 队列/管道

标签:管道   join   empty   join()   display   tpi   数据   示例   put   

原文地址:https://www.cnblogs.com/shijieli/p/10340280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!