2014-10-02 49 views
1

我想弄清楚下面的模塊正在做什麼。multiprocessinq.Queue作爲Queue.Queue子的屬性

import Queue 
import multiprocessing 
import threading 

class BufferedReadQueue(Queue.Queue): 
    def __init__(self, lim=None): 
     self.raw = multiprocessing.Queue(lim) 
     self.__listener = threading.Thread(target=self.listen) 
     self.__listener.setDaemon(True) 
     self.__listener.start() 
     Queue.Queue.__init__(self, lim) 

    def listen(self): 
     try: 
      while True: 
       self.put(self.raw.get()) 
     except: 
      pass 

    @property 
    def buffered(self): 
     return self.qsize() 

它只能在調用代碼實例化一次,.raw屬性,multiprocessing.Queue,被髮送到另一個類,這似乎從multiprocessing.Process繼承。

所以當我看到它時,BufferedReadQueue的一個屬性被用作Queue,但不是它的類(也不是它的一個實例)本身。

如果BufferedReadQueue實際上並未被用作隊列,那麼它會從Queue.Queue繼承而不僅僅是object的原因是什麼?

回答

1

它看起來像BufferedReadQueue意在用作將multiprocessing.Queue的讀取結果轉換爲正常Queue.Queue的方式。注意,這在__init__

self.__listener = threading.Thread(target=self.listen) 
    self.__listener.setDaemon(True) 
    self.__listener.start() 

這將啓動一個監聽線程,只是不斷地嘗試從內部multiprocessing.Queueget項目,然後put一切都是那些項目self。它看起來像用例是這樣的:

def func(queue): 
    queue.put('stuff') 
    ... 

buf_queue = BufferedReadQueue() 
proc = multiprocessing.Process(target=func, args=(buf_queue.raw,)) 
proc.start() 
out = buf_queue.get() # Only get calls in the parent 

現在,你爲什麼會做這個,而不是僅僅使用直接multiprocessing.Queue的?可能因爲multiprocessing.Queue有一些Queue.Queue沒有的缺點。例如qsize(),此BufferedReadQueue用途,is not reliable with multiprocessing.Queue

返回隊列的近似大小。由於多線程/多處理語義,這個數字是不可靠的。

請注意,這可能會引起NotImplementedError在Unix平臺上,如Mac OS X,其中sem_getvalue()未實現。

也可以反思一個Queue.Queue,並且在不彈出它們的情況下查看它的內容。這是不可能的,multiprocessing.Queue

+0

我看到'.buffered'在一個點上被調用。我*仍然*對財產裝飾者感到困惑。在這種情況下,'.buffered'類似於說'self.buffered = self.qsize()',但使它成爲只讀屬性? – MikeiLL 2014-10-02 19:36:29

+1

@MikeiLL無論出於何種原因,作者決定使用'buf_queue.buffered'而不是'buf_queue.qsize()'。也許是因爲該對象意味着是對象緩衝區的抽象,而不是對象隊列,而「緩衝」應該理解爲「有多少對象被緩衝」。或者也許他們希望能夠在將來改變'BufferedReadQueue'的內部實現,這可能意味着'buffered'的值不再是'qsize()'。 – dano 2014-10-02 19:54:29

+0

'Queue.Queue .__ init __(self,lim)'發生了什麼?這是否基本上將'Queue.Queue(lim)'的實例分配給'BufferedReadQueue'的實例? – MikeiLL 2014-10-02 20:19:14