python队列模块Queue
一、初识Queue模块
Queue模块实现了多生产者、多消费者队列。它特别适用于信息必须在多个线程间安全地交换的多线程程序中。这个模块中的Queue类实现了所有必须的锁语义。它依赖于Python中线程支持的可用性;参见threading模块。
模块实现了三类队列:FIFO(First In First Out,先进先出,默认为该队列)、LIFO(Last In First Out,后进先出)、基于优先级的队列。以下为其常用方法:
1先进先出 q = Queue.Queue(maxsize)
2后进先出 a = Queue.LifoQueue(maxsize)
3优先级 Queue.PriorityQueue(maxsize)
4Queue.qsize() 返回队列的大小
5Queue.empty() 如果队列为空,返回True,反之False
6Queue.full() 如果队列满了,返回True,反之False
7Queue.full 与 maxsize 大小对应
8Queue.put(item) 写入队列,timeout等待时间 非阻塞
9Queue.get([block[, timeout]]) 获取队列,timeout等待时间
10Queue.get_nowait() 相当Queue.get(False)
11Queue.put_nowait(item) 相当Queue.put(item, False)
12Queue.task_done() 在完成一项工作之后,函数向任务已经完成的队列发送一个信号
13Queue.join(): 实际上意味着等到队列为空,再执行别的操作
更详细部分可以参看python标准库之Queue模块介绍。
二、队列示列
1、FIFO(先进先出)
1import Queue
2q = Queue.Queue()
3for i in range(5):
4 q.put(i)
5while not q.empty():
6 print q.get()
其输出结果如下:
1[root@361way queue]# python fifo.py
21
32
43
54
其输出顺序与进入顺序相同。
2、LIFO(后进先出)
1import Queue
2q = Queue.LifoQueue()
3for i in range(5):
4 q.put(i)
5while not q.empty():
6 print q.get()
执行结果如下:
1import Queue
2q = Queue.LifoQueue()
3for i in range(5):
4 q.put(i)
5while not q.empty():
6 print q.get()
3、带优先级的队列
1import Queue
2class Job(object):
3 def __init__(self, priority, description):
4 self.priority = priority
5 self.description = description
6 print 'New job:', description
7 return
8 def __cmp__(self, other):
9 return cmp(self.priority, other.priority)
10q = Queue.PriorityQueue()
11q.put( Job(3, 'Mid-level job') )
12q.put( Job(10, 'Low-level job') )
13q.put( Job(1, 'Important job') )
14while not q.empty():
15 next_job = q.get()
16 print 'Processing job:', next_job.description
执行结果如下:
1[root@361way queue]# python Queue_priority.py
2New job: Mid-level job
3New job: Low-level job
4New job: Important job
5Processing job: Important job
6Processing job: Mid-level job
7Processing job: Low-level job
从上面的执行结果可以看出,优先级值设置越小,越先执行。另外这里是以单线程为例的,在多thread的示例中,多个线程同时get() item 时,这时就可以根据优先级决定哪一个任务先执行。
三、队列与线程
在实际使用队列是与线程结合在一起的。这里列几个队列与线程的代码示例:
1from Queue import *
2from threading import Thread
3import sys
4'''this function will process the items in the queue, in serial'''
5def processor():
6 while True:
7 if queue.empty() == True:
8 print "the Queue is empty!"
9 sys.exit(1)
10 try:
11 job = queue.get()
12 print "I'm operating on job item: %s"%(job)
13 queue.task_done()
14 except:
15 print "Failed to operate on job"
16'''set variables'''
17queue = Queue()
18threads = 4
19'''a list of job items. you would want this to be more advanced,
20like reading from a file or database'''
21jobs = [ "job1", "job2", "job3" ]
22'''iterate over jobs and put each into the queue in sequence'''
23#for job in jobs:
24for job in range(100):
25 print "inserting job into the queue: %s"%(job)
26 queue.put(job)
27'''start some threads, each one will process one job from the queue'''
28#for i in range(100):
29for i in range(threads):
30 th = Thread(target=processor)
31 th.setDaemon(True)
32 th.start()
33'''wait until all jobs are processed before quitting'''
34queue.join()
需要注意的是processer函数里的“ while True:”行 ,如果没了这行,当线程(thread)数小于队列数时,第一轮循环完后就会卡住,不执行后面的循环了。所以加上该行,就相当于开始了一个死循环,直到所有的队列结束时,队列为空,循环结束。
示例2:
1[root@361way tmp]# python queue-example-1.py
2task 0 finished
3task 1 finished
4task 3 finished
5task 2 finished
6task 5 finished
7task 4 finished
8task 6 finished
9task 7 finished
10task 9 finished
11task 8 finished
12[root@361way tmp]# more queue-example-1.py
13# File: queue-example-1.py
14import threading
15import Queue
16import time, random
17WORKERS = 2
18class Worker(threading.Thread):
19 def __init__(self, queue):
20 self.__queue = queue
21 threading.Thread.__init__(self)
22 def run(self):
23 while 1:
24 item = self.__queue.get()
25 if item is None:
26 break # reached end of queue
27 # pretend we're doing something that takes 10-100 ms
28 time.sleep(random.randint(10, 100) / 1000.0)
29 print "task", item, "finished"
30#
31# try it
32queue = Queue.Queue(0)
33for i in range(WORKERS):
34 Worker(queue).start() # start a worker
35for i in range(10):
36 queue.put(i)
37for i in range(WORKERS):
38 queue.put(None) # add end-of-queue markers
参考页面:
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/python-queue/4612.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.