python queue的用法_python Queue模块使用
Python中,隊列是線程間最常用的交換數(shù)據(jù)的形式。Queue模塊是提供隊列操作的模塊,雖然簡單易用,但是不小心的話,還是會出現(xiàn)一些意外。
創(chuàng)建一個“隊列”對象
import Queue
q = Queue.Queue(maxsize = 10)
Queue.Queue類即是一個隊列的同步實現(xiàn)。隊列長度可為無限或者有限。可通過Queue的構造函數(shù)的可選參數(shù)maxsize來設定隊列長度。如果maxsize小于1就表示隊列長度無限。
將一個值放入隊列中
q.put(10) ? ?put(item[, block[, timeout]])
將item放入隊列中。
如果可選的參數(shù)block為True且timeout為空對象(默認的情況,阻塞調(diào)用,無超時)。
如果timeout是個正整數(shù),阻塞調(diào)用進程最多timeout秒,如果一直無空空間可用,拋出Full異常(帶超時的阻塞調(diào)用)。
如果block為False,如果有空閑空間可用將數(shù)據(jù)放入隊列,否則立即拋出Full異常
其非阻塞版本為put_nowait等同于put(item, False)
將一個值從隊列中取出
q.get() ? get([block[, timeout]])
調(diào)用隊列對象的get()方法從隊頭刪除并返回一個項目。可選參數(shù)為block,默認為True。如果隊列為空且block為True,get()就使調(diào)用線程暫停,直至有項目可用。如果隊列為空且block為False,隊列將引發(fā)Empty異常。
從隊列中移除并返回一個數(shù)據(jù)。block跟timeout參數(shù)同put方法
其非阻塞方法為`get_nowait()`相當與get(False)
Python Queue模塊有三種隊列及構造函數(shù):
1、Python Queue模塊的FIFO隊列先進先出。???? class Queue.Queue(maxsize)
2、LIFO類似于堆,即先進后出。???????????????????????? class Queue.LifoQueue(maxsize)
3、還有一種是優(yōu)先級隊列級別越低越先出來。 ?? class Queue.PriorityQueue(maxsize)
此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回隊列的大小
q.empty() 如果隊列為空,返回True,反之False
q.full() 如果隊列滿了,返回True,反之False
q.full 與 maxsize 大小對應
q.get([block[, timeout]]) 獲取隊列,timeout等待時間
q.get_nowait() 相當q.get(False)
非阻塞 q.put(item) 寫入隊列,timeout等待時間
q.put_nowait(item) 相當q.put(item, False)
q.task_done() 在完成一項工作之后,向任務已經(jīng)完成的隊列發(fā)送一個信號,每一個get()調(diào)用得到一個任務,接下來的task_done()調(diào)用告訴隊列該任務已經(jīng)處理完畢。如果當前一個join()正在阻塞,它將在隊列中的所有任務都處理完時恢復執(zhí)行(即每一個由put()調(diào)用入隊的任務都有一個對應的task_done()調(diào)用)。
q.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作.阻塞調(diào)用線程,直到隊列中的所有任務被處理掉。
只要有數(shù)據(jù)被加入隊列,未完成的任務數(shù)就會增加。當消費者線程調(diào)用task_done()(意味著有消費者取得任務并完成任務),未完成的任務數(shù)就會減少。當未完成的任務數(shù)降到0,join()解除阻塞。
先進先出:
importQueue
q= Queue.Queue(maxsize=5)for i in range(5):
q.put(i)while notq.empty():print q.get()
結果:
0
1
2
3
4
View Code
先進后出:
q =Queue.LifoQueue()for i in range(5):
q.put(i)while notq.empty():print q.get()
結果:
4
3
2
1
0
View Code
優(yōu)先級:
#優(yōu)先級隊列
importQueueimportthreadingclassJob(object):def __init__(self, priority, description):
self.priority=priority
self.description=descriptionprint 'Job:',descriptionreturn
def __cmp__(self, other): #需要加上這個比較函數(shù),
return cmp(self.priority, other.priority) #Return negative if xy.
q=Queue.PriorityQueue()
q.put(Job(3, 'mid-level job'))
q.put(Job(10, 'low-level job'))
q.put(Job(1, 'high-level job'))defprocess_job(q):whileTrue:
next_job=q.get()print 'for:', next_job.description
q.task_done()
workers= [threading.Thread(target=process_job, args=(q,)),
threading.Thread(target=process_job, args=(q,))
]for w inworkers:
w.setDaemon(True)#守護進程
w.start()
q.join()
View Code
運行結果:
Job: mid-level job
Job: low-level job
Job: high-level jobfor: high-level jobfor: mid-level jobfor: low-level job
View Code
復雜一點的
實現(xiàn)一個線程不斷生成一個隨機數(shù)到一個隊列中(考慮使用Queue這個模塊)
實現(xiàn)一個線程從上面的隊列里面不斷的取出奇數(shù)
實現(xiàn)另外一個線程從上面的隊列里面不斷取出偶數(shù)
#!/usr/bin/python#coding=utf-8#__author__='dahu'#data=2017-#
importrandom, threading, timefrom Queue importQueue#Producer thread
classProducer(threading.Thread):def __init__(self, t_name, queue):#threading.Thread.__init__(self, name=t_name)
super(Producer,self).__init__(name=t_name) #兩個都可以,傾向于這個
self.data =queuedefrun(self):for i in range(5): #隨機產(chǎn)生10個數(shù)字 ,可以修改為任意大小
randomnum = random.randint(1, 20)print "%s: %s is producing %d to the queue!" %(time.ctime(), self.getName(), randomnum)
self.data.put(randomnum)#將數(shù)據(jù)依次存入隊列
time.sleep(1)print "%s: %s finished!" %(time.ctime(), self.getName())#Consumer thread
classConsumer_even(threading.Thread):def __init__(self, t_name, queue):#threading.Thread.__init__(self, name=t_name)
super(Consumer_even, self).__init__(name=t_name)
self.data=queuedefrun(self):while 1:try:
val_even= self.data.get(1, 5) #get(self, block=True, timeout=None) ,1就是阻塞等待,5是超時5秒
if val_even % 2 ==0:print "%s: %s is consuming. %d in the queue is consumed!" %(time.ctime(), self.getName(), val_even)
time.sleep(2)else:
self.data.put(val_even)
time.sleep(2)except: #等待輸入,超過5秒 就報異常
print "%s: %s finished!" %(time.ctime(), self.getName())break
classConsumer_odd(threading.Thread):def __init__(self, t_name, queue):
threading.Thread.__init__(self, name=t_name)
self.data=queuedefrun(self):while 1:try:
val_odd= self.data.get(1, 5)if val_odd % 2 !=0:print "%s: %s is consuming. %d in the queue is consumed!" %(time.ctime(), self.getName(), val_odd)
time.sleep(2)else:
self.data.put(val_odd)
time.sleep(2)except:print "%s: %s finished!" %(time.ctime(), self.getName())break
#Main thread
defmain():
queue=Queue()
producer= Producer('Pro.', queue)
consumer_even= Consumer_even('Con_even.', queue)
consumer_odd= Consumer_odd('Con_odd.', queue)
producer.start()
consumer_even.start()
consumer_odd.start()
producer.join()
consumer_even.join()
consumer_odd.join()print 'All threads terminate!'
if __name__ == '__main__':
main()
View Code
結果:
/usr/bin/python2.7 /home/dahu/PycharmProjects/SpiderLearning/request_lianxi/t9.queue.thread.py
Tue Aug22 16:12:25 2017: Pro. is producing 15 to the queue!Tue Aug22 16:12:25 2017: Con_odd. is consuming. 15 in the queue is consumed!Tue Aug22 16:12:26 2017: Pro. is producing 17 to the queue!Tue Aug22 16:12:27 2017: Pro. is producing 2 to the queue!Tue Aug22 16:12:27 2017: Con_odd. is consuming. 17 in the queue is consumed!Tue Aug22 16:12:28 2017: Pro. is producing 15 to the queue!Tue Aug22 16:12:29 2017: Con_even. is consuming. 2 in the queue is consumed!Tue Aug22 16:12:29 2017: Con_odd. is consuming. 15 in the queue is consumed!Tue Aug22 16:12:29 2017: Pro. is producing 18 to the queue!Tue Aug22 16:12:30 2017: Pro. finished!Tue Aug22 16:12:31 2017: Con_even. is consuming. 18 in the queue is consumed!Tue Aug22 16:12:38 2017: Con_odd. finished!Tue Aug22 16:12:38 2017: Con_even. finished!All threads terminate!Process finished with exit code0
總結
以上是生活随笔為你收集整理的python queue的用法_python Queue模块使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: head.s 剖析——Linux-0.1
- 下一篇: C 语言内联汇编介绍