• Python 队列(Queue)用法


    一、队列(Queue)

    Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。

    常用方法:

    • Queue.qsize() 返回队列的大小
    • Queue.empty() 如果队列为空,返回True,反之False
    • Queue.full() 如果队列满了,返回True,反之False,Queue.full 与 maxsize 大小对应
    • Queue.get([block[, timeout]])获取队列,timeout等待时间
    • Queue.get_nowait() 相当于Queue.get(False),非阻塞方法
    • Queue.put(item) 写入队列,timeout等待时间
    • Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号。每个get()调用得到一个任务,接下来task_done()调用告诉队列该任务已经处理完毕。
    • Queue.join() 实际上意味着等到队列为空,再执行别的操作

    示例代码如下:

    1.  
      from Queue import Queue,LifoQueue,PriorityQueue
    2.  
      #先进先出队列
    3.  
      q=Queue(maxsize=5)
    4.  
      #后进先出队列
    5.  
      lq=LifoQueue(maxsize=6)
    6.  
      #优先级队列
    7.  
      pq=PriorityQueue(maxsize=5)
    8.  
       
    9.  
      for i in range(5):
    10.  
      q.put(i)
    11.  
      lq.put(i)
    12.  
      pq.put(i)
    13.  
       
    14.  
      print "先进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(q.queue,q.empty(),q.qsize(),q.full())
    15.  
      print "后进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full())
    16.  
      print "优先级队列:%s;是否为空:%s,多大,%s;是否满,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full())
    17.  
       
    18.  
      print q.get(),lq.get(),pq.get()
    19.  
       
    20.  
      print "先进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(q.queue,q.empty(),q.qsize(),q.full())
    21.  
      print "后进先出队列:%s;是否为空:%s;多大,%s;是否满,%s" %(lq.queue,lq.empty(),lq.qsize(),lq.full())
    22.  
      print "优先级队列:%s;是否为空:%s,多大,%s;是否满,%s" %(pq.queue,pq.empty(),pq.qsize(),pq.full())
    1.  
      先进先出队列:deque([0, 1, 2, 3, 4]);是否为空:False;多大,5;是否满,True
    2.  
      后进先出队列:[0, 1, 2, 3, 4];是否为空:False;多大,5;是否满,False
    3.  
      优先级队列:[0, 1, 2, 3, 4];是否为空:False,多大,5;是否满,True
    4.  
      0 4 0
    5.  
      先进先出队列:deque([1, 2, 3, 4]);是否为空:False;多大,4;是否满,False
    6.  
      后进先出队列:[0, 1, 2, 3];是否为空:False;多大,4;是否满,False
    7.  
      优先级队列:[1, 3, 2, 4];是否为空:False,多大,4;是否满,False

     还有一种队列是双边队列,示例代码如下:

    1.  
      from Queue import deque
    2.  
      dq=deque(['a','b'])
    3.  
      dq.append('c')
    4.  
      print dq
    5.  
      print dq.pop()
    6.  
      print dq
    7.  
      print dq.popleft()
    8.  
      print dq
    9.  
      dq.appendleft('d')
    10.  
      print dq
    11.  
      print len(dq)
    1.  
      deque(['a', 'b', 'c'])
    2.  
      c
    3.  
      deque(['a', 'b'])
    4.  
      a
    5.  
      deque(['b'])
    6.  
      deque(['d', 'b'])
    7.  
      2

     二、生产者消费者模式

    生产者消费者模式并不是GOF提出的众多模式之一,但它依然是开发同学编程过程中最常用的一种模式

    生产者模块儿负责产生数据,放入缓冲区,这些数据由另一个消费者模块儿来从缓冲区取出并进行消费者相应的处理。该模式的优点在于:

    • 解耦:缓冲区的存在可以让生产者和消费者降低互相之间的依赖性,一个模块儿代码变化,不会直接影响另一个模块儿
    • 并发:由于缓冲区,生产者和消费者不是直接调用,而是两个独立的并发主体,生产者产生数据之后把它放入缓冲区,就继续生产数据,不依赖消费者的处理速度

    三、采用生产者消费者模式开发的Python多线程

    在Python中,队列是最常用的线程间的通信方法,因为它是线程安全的,自带锁。而Condition等需要额外加锁的代码操作,在编程对死锁现象要很小心,Queue就不用担心这个问题。

    Queue多线程代码示例如下:

    1.  
      from Queue import Queue
    2.  
      import time,threading
    3.  
      q=Queue(maxsize=0)
    4.  
       
    5.  
      def product(name):
    6.  
      count=1
    7.  
      while True:
    8.  
      q.put('气球兵{}'.format(count))
    9.  
      print ('{}训练气球兵{}只'.format(name,count))
    10.  
      count+=1
    11.  
      time.sleep(5)
    12.  
      def consume(name):
    13.  
      while True:
    14.  
      print ('{}使用了{}'.format(name,q.get()))
    15.  
      time.sleep(1)
    16.  
      q.task_done()
    17.  
      t1=threading.Thread(target=product,args=('wpp',))
    18.  
      t2=threading.Thread(target=consume,args=('ypp',))
    19.  
      t3=threading.Thread(target=consume,args=('others',))
    20.  
       
    21.  
      t1.start()
    22.  
      t2.start()
    23.  
      t3.start()

    网上还有很多非常好的生产者消费者模式的Queue代码例子,开发同学需要根据具体的实际需求去设计实际模式

  • 相关阅读:
    微软企业库4.1学习笔记(二十六)Unity依赖注入模块3
    微软企业库4.1学习笔记(三十七)日志模块 在应用中使用日志模块
    微软企业库5.0学习笔记(三十五)数据访问模块 DataSet以及数据库事务
    微软企业库4.1学习笔记(四十一)依赖注入模块Unity 简介
    项目统一开发管理解决方案思路[项目组成员同时做很多项目的解决思路探讨]
    在moss2007WEB应用服务器上发布独立web程序时遇到的问题的解决思路
    工作流表单自定义的误区
    文档库创建的子文件夹的URL显示为 http://[机器名]/.... 导致无法正常访问的问题解决办法
    申请加入 .NET企业应用开发 博客团队请回复
    儿子照片
  • 原文地址:https://www.cnblogs.com/alex-13/p/14046908.html
Copyright © 2020-2023  润新知