• 4.3 队列/管道


    IPA 通信

    概念原理

    创建/方法

    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

    生产者消费者模型

    无信号纯阻塞的模型

    from multiprocessing import Process,Queue
    import time,random,os
    def consumer(q):
        while True:
            res=q.get()
            time.sleep(random.randint(1,3))
            print('33[45m%s 吃 %s33[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('33[44m%s 生产了 %s33[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('33[45m%s 吃 %s33[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('33[44m%s 生产了 %s33[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('33[45m%s 吃 %s33[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('33[44m%s 生产了 %s33[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
  • 相关阅读:
    Oracle数据库管理员经常使用的表和视图
    oracle重建、更新索引、索引统计信息命令
    oracle查看死锁和处理方法
    2013秋季校招,你准备好了吗?
    oracle:变长数组varray,嵌套表,集合
    HTTPS是如何保证连接安全:每位Web开发者都应知道的
    CTE在Oracle和Sqlserver中使用的差异
    NUll在oracle与sqlserver中使用相同与区别
    linux中history命令使用与配置
    权限访问控制设计
  • 原文地址:https://www.cnblogs.com/shijieli/p/10340280.html
Copyright © 2020-2023  润新知