5.Python的Queue模块
来源:互联网 发布:java线程 pdf 编辑:程序博客网 时间:2024/05/14 13:27
转载*请注明原始出处: http://blog.csdn.net/a464057216/article/details/48103125
Queue模块提供了对“多生产者,多消费者”队列模型的支持,是线程安全的模块,在多线程之间传递数据时尤其有用。如果只是想使用队列这种数据结构,可以参考collections.deque模块。
Queue模块内包含三种队列:
- class Queue.Queue(maxsize = 0):FIFO队列,maxsize指定了队列的大小,如果队列已满,将不能插入新的元素,除非队列中有元素被消耗。如果maxsize为零或者负数,则队列的大小是无限大。
- class Queue.LifoQueue(maxsize = 0):LIFO队列,maxsize的含义与Queue.Queue中一致。
- class Queue.PriorityQueue(maxsize = 0):优先级队列(内部其实由heapq模块实现),maxsize的含义与Queue.Queue中一致。优先级最小的项目被优先取出,优先级的排序其实是根据sorted(list(entries)[0])的结果,每个项目的格式是(priority_number, data)的元组。
Queue模块还有两种异常,是上面三种队列公用的:
- exception Queue.Empty:当一个Queue对象中无元素,却对这个Queue对象调用了非阻塞的get()或者get_nowait()方法的时候抛出。
- exception Queue.Full:当一个Queue对象中元素已满,却对这个Queue对象调用了非阻塞的put()或者put_nowait()方法的时候抛出。
Queue模块还提供了如下几种操作队列的方法,都是上面三种队列公用的:
- Queue.qsize():返回队列的近似大小。如果qsize()的返回值大于零,不代表接下来的get()操作不会被阻塞,同样,如果qsize()的返回值小于maxsize,也不代表接下来的put()操作不会被阻塞。
- Queue.empty():如果队列为空,返回True,否则返回False。如果empty()的返回值是True,不代表接下来的put()操作不会被阻塞,同样,如果empty()的返回值是False,不代表接下来的get()操作不会被阻塞。
- Queue.full():如果队列满,返回True,否则返回False。如果full()的返回值是True,不代表接下来的get()操作不会被阻塞,同样,如果full()的返回值是False,不代表接下来的put()操作不会被阻塞。
- Queue.put(item, block = True, timeout = None):向队列中添加元素。如果block = True,则当队列已满时,会一直阻塞(只能阻塞执行线程本身,不能阻塞其他线程)到队列中有空余位置时再添加元素。如果block = True时,设置了timeout,则会一直阻塞timeout时间,到时有空余位置就添加元素,没有空余位置就抛出Queue.Full异常。如果block = False,则忽略timeout参数,是非阻塞插入,如果有空余位置就添加元素,如果没有空余位置就直接抛出Queue.Full异常。
- Queue.put_nowait(item):相当于put(item, block = False)。
- Queue.get(block = True, timeout = None):从队列中取出一个元素。如果block = True,则当队列中无元素时,会一直阻塞等到队列中有一个元素时再取出。如果block = True时,设置了timeout,则会一直等待timeout时间,到时如果队列中有元素就取出,如果没有就抛出Queue.Empty异常。如果block = False,则忽略timeout参数,是非阻塞取出,如果有元素就取出,没有元素直接抛出Queue.Empty异常。
- Queue.get_nowait():相当与get(block = False)。
先举一个单线程使用Queue.Queue的例子:
import Queuequeue = Queue.Queue(3)queue.put(6)print 'After put 6, queue size:', queue.qsize()print 'Put 2.'queue.put(2)print 'Is queue full?:', queue.full()print 'Is queue empty?:', queue.empty()print 'Put 4.'queue.put(4)print 'Is queue full?:', queue.full()item = queue.get()print 'Item getted:', item
执行结果如下:
After put 6, queue size: 1Put 2.Is queue full?: FalseIs queue empty?: FalsePut 4.Is queue full?: TrueItem getted: 6
后进先出队列与Queue.Queue类似,在此不再举例,下面是一个优先级队列的例子:
import Queuequeue = Queue.PriorityQueue(3)queue.put((2,'Two'))queue.put((1,'One'))queue.put((6,'Six'))item = queue.get()print 'Item getted:', item
执行结果如下:
mars@mars-Ideapad-V460:~/test$ python test2.pyItem getted: (1, 'One')
针对“多生产者,多消费者”模型,Queue模块还提供了如下两个方法跟踪入队列的元素的处理情况:
- Queue.task_done():通常由消费者线程调用,表示之前get()到的元素已经处理完毕,通知给Queue。如果task_done()的调用次数比队列中的元素多,会抛出ValueError异常。
- Queue.join():阻塞线程,直到队列中的所有元素被处理完毕。向队列中添加元素会使未处理元素个数加1,从队列中取出元素会使未处理元素个数减1,如果未处理元素个数降至0,join解除阻塞。
下面先举一个简单的多线程例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @author: Mars Looimport threadingimport Queueimport timeclass Producer(threading.Thread): def __init__(self, q): self.q = q super(Producer, self).__init__() def run(self): time.sleep(1) self.q.put(3)class Consumer(threading.Thread): def __init__(self, q): self.q = q super(Consumer, self).__init__() def run(self): while True: try: print 'Start to get' item = self.q.get_nowait() print 'Got the item:', item print 'Got time:', time.ctime() break except Exception, exc: print excst = time.ctime()q = Queue.Queue(3)c = Consumer(q)p = Producer(q)p.start()c.start()c.join()print 'Task begin time:', st
执行结果如下:
Start to get(还有很多Start to get的显示,奇怪的是异常抓不到)Start to getStart to getStart to getStart to getStart to getStart to getGot the item: 3Got time: Sun Aug 30 20:44:55 2015Task begin time: Sun Aug 30 20:44:54 2015
如果采用get的阻塞版本:
def run(self): while True: try: print 'Start to get' item = self.q.get() print 'Got the item:', item print 'Got time:', time.ctime() break except Exception, exc: print exc
执行结果变成这样:
mars@mars-Ideapad-V460:~/test$ python test.pyStart to getGot the item: 3Got time: Sun Aug 30 20:46:21 2015Task begin time: Sun Aug 30 20:46:20 2015
下面举一个使用task_done和join的例子:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @author: Mars Looimport threadingimport Queueimport time, randomdef worker(q): while True: item = q.get() print 'Working on', item time.sleep(random.randint(1,100)/100.0) q.task_done()q = Queue.Queue()for i in range(15): t = threading.Thread(target = worker, args = (q,)) t.setDaemon(True) t.start()for item in range(50,60): q.put(item)q.join()print 'All done!'
执行结果如下:
mars@mars-Ideapad-V460:~/test$ python test.pyWorking on Working on Working on5150 52Working on Working onWorking on 53 5554 Working on 56Working onWorking on 58Working on 59 57All done!
如果觉得我的文章对您有帮助,欢迎关注我(CSDN:Mars Loo的博客)或者为这篇文章点赞,谢谢!
- 5.Python的Queue模块
- [Python] python Queue模块
- python Queue模块
- python Queue模块
- python Queue模块
- python Queue模块
- python Queue模块
- python模块学习---Queue
- python Queue模块
- Python中的Queue模块
- Python Queue模块
- python queue模块
- Python Queue模块详解
- Python Queue模块详解
- Python Queue模块详解
- Python队列Queue模块
- Python 中的queue模块
- Python Queue模块详解
- 考评系统学到的UI设计理念
- 1035. Password (20)
- java字符串常见问题
- 自己和自己结婚
- 使用Scanner获取键盘输入
- 5.Python的Queue模块
- (3)使用Highcharts开发JVM监控内存
- 590 相同的和【枚举】
- Bear and Poker
- Python getopt模块
- 因为有你,机房收费大大不同(细节功能实现)
- 1097. Deduplication on a Linked List
- Codeforces Round #318(Div. 2)(A,B,C,D)
- JSP页面的五种跳转方法