2011-05-07 83 views
1

我有一個主進程生成進程,然後這些進程將作業添加到主進程用於產生更多進程的隊列。並且,這工作正常約20秒,然後主進程停止產卵工作,即使它在隊列中有大量工作。Python隊列似乎正在死亡

這裏的作業過程的運行循環的代碼:

try: 
    page = self.fetch_page(self.url, self.timeout) 
    if page != None: 
     #do_stuff 
     pass 
except Exception, e:       #Log any errors 
    import traceback 
    self.log(str(traceback.format_exc(limit=10)), level="error") 
    self.log(str(e), level="error") 
finally: 
    import os, signal 
    print "releasing Semaphore" 
    self.__sem.release() 
    #print "Joining pQueue" #these statements raise errors... 
    #self.__pqueue.join_thread() 
    #print "Joining lQueue" 
    #self.__log.join_thread() 
    print "exiting" 
    os._exit(1) 
    #os.kill(self.pid, signal.SIGTERM) 

及這裏的派生的就業崗位主要工序中的代碼:

while True: 
    print "Waiting for url" 
    url = self.page_queue.get() 
    print "waiting for semaphore" 
    self.__sem.acquire() 
    print "semaphore recived" 
    process = self.process_handler(url, self.log_queue, self.__sem, self.page_queue) 
    process.start() 

只是一個小範圍內,self.log_queue在產卵過程是自我.__登錄Job過程,self.page_queue在Job過程中是self .__ pqueue,而self .__ sem與Job過程中的self .__ sem相同。

的spawing過程通常掛在:

url = self.page_queue.get() 

我敢肯定是有事情做與隊列打破時,工作進程終止他們完成寫入隊列前,但是這只是一個直覺。和self .__ pqueue.join_thread()引發了斷言錯誤。

+0

如何實例化您的信號量?如果初始值太小,您將無法處理許多進程。 – 2011-05-07 19:07:10

+0

你怎麼知道隊列中有很多工作? – 2011-05-07 21:39:07

+0

@Cedric Julien它在主進程中初始化,然後作爲參數傳遞給進程。在約1進程的比率它初始化爲5 – Joshkunz 2011-05-10 18:20:10

回答

0

好吧,我弄明白了。我的第一個預感是隊列在寫作中被殺害。然而,在使用Queue.qsize()檢查確定隊列中有值之後,我開始認爲這是導致問題的信號量。所以我研究了多處理Manager對象,這些對象允許進程通過「代理」來操縱他們的數據。所以我切換了邏輯,以便所有的隊列和信號都由Manager對象來控制,並且似乎已經完美實現了。鏈接到適用的python文檔:http://docs.python.org/library/multiprocessing.html#sharing-state-between-processes

1

不確定這是否有用,但是如果您的self.page_queue是隊列(http://docs.python.org/library/queue.html)的實例,那麼默認情況下get()會被阻止。你確認隊列不是空的嗎?它可能只是等待一件物品而已。我記得當我使用隊列時困擾了我。

而且,它不會加入到爲您做一個get()每一項任務,你叫task_done()

+0

我會嘗試queue.empty的東西。就程序而言,它使用的是多處理隊列而不是Queue.Queue對象,所以沒有task_done() – Joshkunz 2011-05-10 18:23:31

1

如果您取的網頁,因爲它出現時,您應考慮使用eventlet庫,而不是多個進程。如果您正在進行大量計算,那麼分成多個進程是非常有用的。但是,您可能會花大部分時間等待Internet連接。結果,啓動進程的額外開銷被浪費了。

Eventlet適用於協作式線程模型,使得編寫這種應用程序變得更容易。

+0

eventlet看起來很酷我當時並不知道它。我會確保檢查出來。 +1 – Joshkunz 2011-05-10 18:25:24