1. 程式人生 > >Python之queue模組

Python之queue模組

  queue模組實現了多生產者,多消費者的佇列。當要求資訊必須在多執行緒間安全交換,這個模組在同步執行緒程式設計時非常有用 ,Queue模組實現了所有要求的鎖機制。 

  內部實現是在搶佔式執行緒加上臨時鎖,但是沒有涉及如何去處理執行緒的重入

1. queue模組的內容

(1)class queue.Queue(maxsize = 0)

  構造一個FIFO佇列,maxsize可以限制佇列的大小。如果佇列的大小達到了佇列的上限,就會加鎖,直到佇列的內容被消費掉。如果maxsize的值小於等於0,那麼佇列的尺寸就是無限制的

(2)class queue.LifoQueue(maxsize = 0)

  構造一個LIFO佇列

(3)class PriorityQueue(maxsize = 0)

  構造一個優先順序佇列,優先順序最低的先出去,優先順序最低的一般使用sorted(list(entries))[0]),典型加入的元素是一個元祖(優先順序, 資料) 

(4)queue.empty異常

  只有非阻塞的時候,佇列為空,取資料才會報異常

(5)queue.Full異常

  只有非阻塞的時候,佇列滿了,繼續放資料才會出現異常

2. 佇列物件的方法

(1)Queue.qsize()

  返回queue的近似值

  注意:qsize>0 不保證(get)取元素不阻塞。qsize< maxsize不保證(put)存元素不會阻塞

(2)Queue.empty()

  判斷佇列是否為空

(3)Queue.full()

  判斷是否滿了

(4)Queue.put(item, block=True, timeout=None):

  往佇列裡放資料,如果滿了的話,blocking = False 直接報 Full異常;如果blocking = True,就是等一會,timeout必須為 0 或正數。None為一直等下去,0為不等,正數n為等待n秒還不能存入,報Full異常。

(5)Queue.put_nowait(item)

  往佇列裡存放元素,不等待

(6)Queue.get(item, block=True, timeout=None):

  從佇列裡取資料,如果為空的話,blocking = False 直接報 empty異常。如果blocking = True,就是等一會,timeout必須為 0 或正數。None為一直等下去,0為不等,正數n為等待n秒還不能讀取,報empty異常。

(7)Queue.get_nowait(item)

  從佇列裡取元素,不等待

  put_nowait和get_nowait兩個方法跟蹤入隊的任務是否被消費者daemon程序完全消費

 (8)Queue.task_done()

  表示佇列中某個元素被消費程序或執行緒使用,消費結束髮送資訊。

(9)Queue.join()

  一直阻塞直到佇列中的所有元素都被取出和執行

3. 簡單示例

import threading
from queue import Queue

class ClosableQueue(Queue):
    SENTINEL = object()
    
    def close(self):
        self.put(SENTINEL)
        
    def __iter__(self):
        while True:
            item = self.get()
            try:
                if item is self.SENTINEL:
                    return 
                yield item
            finally:
                self.task_done()
                
class StoppabelWoker(threading.Thread):
    def __init__(self,func,in_queue,out_queue):
        self.func = func
        self.in_queue = in_queue
        self.out_queue = out_queue
    
    def run(self):
        for item in self.in_queue:
            result = self.func(item)
            self.out_queue.put(result)