Python中,隊(duì)列是線程間最常用的交換數(shù)據(jù)的形式。Queue模塊是提供隊(duì)列操作的模塊,雖然簡(jiǎn)單易用,但是不小心的話,還是會(huì)出現(xiàn)一些意外。
創(chuàng)建一個(gè)“隊(duì)列”對(duì)象
import Queue
q = Queue.Queue(maxsize = 10)
Queue.Queue類即是一個(gè)隊(duì)列的同步實(shí)現(xiàn)。隊(duì)列長(zhǎng)度可為無(wú)限或者有限??赏ㄟ^(guò)Queue的構(gòu)造函數(shù)的可選參數(shù)maxsize來(lái)設(shè)定隊(duì)列長(zhǎng)度。如果maxsize小于1就表示隊(duì)列長(zhǎng)度無(wú)限。
將一個(gè)值放入隊(duì)列中
q.put(10)
調(diào)用隊(duì)列對(duì)象的put()方法在隊(duì)尾插入一個(gè)項(xiàng)目。put()有兩個(gè)參數(shù),第一個(gè)item為必需的,為插入項(xiàng)目的值;第二個(gè)block為可選參數(shù),默認(rèn)為
1。如果隊(duì)列當(dāng)前為空且block為1,put()方法就使調(diào)用線程暫停,直到空出一個(gè)數(shù)據(jù)單元。如果block為0,put方法將引發(fā)Full異常。
將一個(gè)值從隊(duì)列中取出
q.get()
調(diào)用隊(duì)列對(duì)象的get()方法從隊(duì)頭刪除并返回一個(gè)項(xiàng)目??蛇x參數(shù)為block,默認(rèn)為T(mén)rue。如果隊(duì)列為空且block為T(mén)rue,get()就使調(diào)用線程暫停,直至有項(xiàng)目可用。如果隊(duì)列為空且block為False,隊(duì)列將引發(fā)Empty異常。
Python Queue模塊有三種隊(duì)列及構(gòu)造函數(shù):
1、Python Queue模塊的FIFO隊(duì)列先進(jìn)先出。 class Queue.Queue(maxsize)
2、LIFO類似于堆,即先進(jìn)后出。 class Queue.LifoQueue(maxsize)
3、還有一種是優(yōu)先級(jí)隊(duì)列級(jí)別越低越先出來(lái)。 class Queue.PriorityQueue(maxsize)
此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回隊(duì)列的大小
q.empty() 如果隊(duì)列為空,返回True,反之False
q.full() 如果隊(duì)列滿了,返回True,反之False
q.full 與 maxsize 大小對(duì)應(yīng)
q.get([block[, timeout]]) 獲取隊(duì)列,timeout等待時(shí)間
q.get_nowait() 相當(dāng)q.get(False)
非阻塞 q.put(item) 寫(xiě)入隊(duì)列,timeout等待時(shí)間
q.put_nowait(item) 相當(dāng)q.put(item, False)
q.task_done() 在完成一項(xiàng)工作之后,q.task_done() 函數(shù)向任務(wù)已經(jīng)完成的隊(duì)列發(fā)送一個(gè)信號(hào)
q.join() 實(shí)際上意味著等到隊(duì)列為空,再執(zhí)行別的操作
范例:
實(shí)現(xiàn)一個(gè)線程不斷生成一個(gè)隨機(jī)數(shù)到一個(gè)隊(duì)列中(考慮使用Queue這個(gè)模塊)
實(shí)現(xiàn)一個(gè)線程從上面的隊(duì)列里面不斷的取出奇數(shù)
實(shí)現(xiàn)另外一個(gè)線程從上面的隊(duì)列里面不斷取出偶數(shù)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
#!/usr/bin/env python #coding:utf8 import random,threading,time from Queue import Queue #Producer thread class Producer(threading.Thread): def __init__( self , t_name, queue): threading.Thread.__init__( self ,name = t_name) self .data = queue def run( self ): for i in range ( 10 ): #隨機(jī)產(chǎn)生10個(gè)數(shù)字 ,可以修改為任意大小 randomnum = random.randint( 1 , 99 ) print "%s: %s is producing %d to the queue!" % (time.ctime(), self .getName(), randomnum) self .data.put(randomnum) #將數(shù)據(jù)依次存入隊(duì)列 time.sleep( 1 ) print "%s: %s finished!" % (time.ctime(), self .getName()) #Consumer thread class Consumer_even(threading.Thread): def __init__( self ,t_name,queue): threading.Thread.__init__( self ,name = t_name) self .data = queue def run( self ): while 1 : try : val_even = self .data.get( 1 , 5 ) #get(self, block=True, timeout=None) ,1就是阻塞等待,5是超時(shí)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 : #等待輸入,超過(guò)5秒 就報(bào)異常 print "%s: %s finished!" % (time.ctime(), self .getName()) break class Consumer_odd(threading.Thread): def __init__( self ,t_name,queue): threading.Thread.__init__( self , name = t_name) self .data = queue def run( 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 def main(): 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() |