2018年4月1日 星期日

[ Python 文章收集 ] Python Queue 模塊詳解

Source From Here 
Preface 
Python中,佇列 (First In First Out) 是線程間最常用的交換數據的形式。Queue 模塊 是提供佇列操作的模塊,雖然簡單易用,但是不小心的話,還是會出現一些意外。 

創建一個 “佇列” 對象 
  1. import Queue  
  2. q = Queue.Queue(maxsize = 10)  
Queue.Queue 類即是一個佇列的同步實現。佇列長度可為無限或者有限。可通過 Queue 的構造函數的可選參數 maxsize 來設定隊列長度。如果 maxsize 小於 1 就表示隊列長度無限。 

將一個值放入隊列中 
  1. // Queue.put(item[, block[, timeout]])  
  2. q.put(10)  
調用佇列對象的 put() 方法在隊尾插入一個項目。put() 有兩個參數,第一個 item 為必需的,為插入項目的值;第二個 block 參數與第三個參數 timeout 為可選參數: 
Put item into the queue. If optional args block is true and timeout is None (the default), block if necessary until a free slot is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Full exception if no free slot was available within that time. Otherwise (block is false), put an item on the queue if a free slot is immediately available, else raise the Full exception (timeout is ignored in that case).

將一個值從隊列中取出 
  1. // Queue.get([block[, timeout]])  
  2. q.get()  
調用隊列對象的 get() 方法從隊頭刪除並返回一個項目。可選參數為 block,默認為True。如果隊列為空且 block 為True,get() 就使調用線程暫停,直至有項目可用 (此時 timeout 參數為 None)。如果隊列為空且 block 為False,隊列將引發 Empty 異常。詳細說明如下: 
Remove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Emptyexception if no item was available within that time. Otherwise (block is false), return an item if one is immediately available, else raise the Empty exception (timeout is ignored in that case).


Python Queue 模塊有三種佇列及構造函數: 
1. Python Queue 模塊的 FIFO 佇列先進先出。class Queue.Queue(maxsize) 
2、LIFO 類似於堆疊,即先進後出。class Queue.LifoQueue(maxsize) 
3、還有一種是優先級隊列級別越低越先出來。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) 
* put(item[, block[, timeout]]): 取出置入項目 
* q.put_nowait(item): 相當 q.put(item, False) 
* q.task_done(): 在完成一項工作之後,q.task_done() 函數向任務已經完成的隊列發送一個信號 
* q .join(): 實際上意味著等到佇列為空,再執行別的操作 

範例: 
* 實現一個線程不斷生成一個隨機數到一個隊列中 (考慮使用 Queue 這個模塊) 
* 實現一個線程從上面的隊列裡面不斷的取出奇數 
* 實現另外一個線程從上面的隊列裡面不斷取出偶數 
- Demo.py 
  1. #!/usr/bin/env python  
  2. #coding:utf8  
  3. import random,threading,time  
  4. from Queue import Queue  
  5. #Producer thread  
  6. class Producer(threading.Thread):  
  7.     def __init__(self, t_name, queue):  
  8.         threading.Thread.__init__(self,name=t_name)  
  9.         self.data=queue  
  10.     def run(self):  
  11.         for i in range(10):    # Randomly generte 10 numbers  
  12.             randomnum=random.randint(1, 99)  
  13.             print "%s: %s is producing %d to the queue!" % (time.ctime(), self.getName(), randomnum)  
  14.             self.data.put(randomnum)  # Put the generated number into queue  
  15.             time.sleep(1)  
  16.         print "%s: %s finished!" %(time.ctime(), self.getName())  
  17.   
  18.   
  19. #Consumer thread  
  20. class Consumer_even(threading.Thread):  
  21.     def __init__(self,t_name,queue):  
  22.         threading.Thread.__init__(self,name=t_name)  
  23.         self.data=queue  
  24.     def run(self):  
  25.         while 1:  
  26.             try:  
  27.                 val_even = self.data.get(True, 5)  # get(self, block=True, timeout=None), Block at most 5 seconds  
  28.                 if val_even%2==0:  
  29.                     print "%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(),self.getName(),val_even)  
  30.                     time.sleep(2)  
  31.                 else:  
  32.                     self.data.put(val_even)  
  33.                     time.sleep(2)  
  34.             except:     # Wait for input and throw excetion when timeout  
  35.                 print "%s: %s finished!" %(time.ctime(),self.getName())  
  36.                 break  
  37.   
  38.   
  39. class Consumer_odd(threading.Thread):  
  40.     def __init__(self,t_name,queue):  
  41.         threading.Thread.__init__(self, name=t_name)  
  42.         self.data=queue  
  43.     def run(self):  
  44.         while 1:  
  45.             try:  
  46.                 val_odd = self.data.get(1,5)  
  47.                 if val_odd%2!=0:  
  48.                     print "%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(), self.getName(), val_odd)  
  49.                     time.sleep(2)  
  50.                 else:  
  51.                     self.data.put(val_odd)  
  52.                     time.sleep(2)  
  53.             except:  
  54.                 print "%s: %s finished!" % (time.ctime(), self.getName())  
  55.                 break  
  56.   
  57.   
  58. #Main thread  
  59. def main():  
  60.     queue = Queue()  
  61.     producer = Producer('Pro.', queue)  
  62.     consumer_even = Consumer_even('Con_even.', queue)  
  63.     consumer_odd = Consumer_odd('Con_odd.',queue)  
  64.     producer.start()  
  65.     consumer_even.start()  
  66.     consumer_odd.start()  
  67.     producer.join()  
  68.     consumer_even.join()  
  69.     consumer_odd.join()  
  70.     print 'All threads terminate!'  
  71.   
  72.   
  73. if __name__ == '__main__':  
  74.     main()  
One example output: 
Mon Apr 2 11:45:30 2018: Pro. is producing 50 to the queue! 
Mon Apr 2 11:45:30 2018: Con_even. is consuming. 50 in the queue is consumed! 
Mon Apr 2 11:45:31 2018: Pro. is producing 58 to the queue! 
Mon Apr 2 11:45:32 2018: Pro. is producing 9 to the queue! 
Mon Apr 2 11:45:32 2018: Con_even. is consuming. 58 in the queue is consumed! 
Mon Apr 2 11:45:33 2018: Pro. is producing 93 to the queue! 
Mon Apr 2 11:45:33 2018: Con_odd. is consuming. 9 in the queue is consumed! 
Mon Apr 2 11:45:34 2018: Pro. is producing 86 to the queue! 
Mon Apr 2 11:45:35 2018: Pro. is producing 34 to the queue! 
Mon Apr 2 11:45:35 2018: Con_odd. is consuming. 93 in the queue is consumed! 
Mon Apr 2 11:45:36 2018: Con_even. is consuming. 86 in the queue is consumed! 
Mon Apr 2 11:45:36 2018: Pro. is producing 15 to the queue! 
Mon Apr 2 11:45:37 2018: Pro. is producing 4 to the queue! 
Mon Apr 2 11:45:38 2018: Pro. is producing 73 to the queue! 
Mon Apr 2 11:45:39 2018: Pro. is producing 45 to the queue! 
Mon Apr 2 11:45:40 2018: Con_even. is consuming. 34 in the queue is consumed! 
Mon Apr 2 11:45:40 2018: Pro. finished! 
Mon Apr 2 11:45:41 2018: Con_odd. is consuming. 15 in the queue is consumed! 
Mon Apr 2 11:45:43 2018: Con_odd. is consuming. 45 in the queue is consumed! 
Mon Apr 2 11:45:44 2018: Con_even. is consuming. 4 in the queue is consumed! 
Mon Apr 2 11:45:45 2018: Con_odd. is consuming. 73 in the queue is consumed! 
Mon Apr 2 11:45:51 2018: Con_even. finished! 
Mon Apr 2 11:45:52 2018: Con_odd. finished! 
All threads terminate!


沒有留言:

張貼留言

[ Py DS ] Ch1 - IPython: Beyond Normal Python

Source From  Here   Keyboard Shortcuts in the IPython Shell   If you spend any amount of time on the computer, you’ve probably found a u...