2012-03-18 125 views
2

我有一些麻煩[可能]關閉我的解析器中的進程池。當所有任務完成後,它掛起並且什麼都不做,CPU使用率大約爲1%。Python多處理map_async掛起

profiles_pool = multiprocessing.Pool(processes=4) 
pages_pool = multiprocessing.Pool(processes=4) 

m = multiprocessing.Manager() 
pages = m.list(['URL']) 
pages_done = m.list() 

while True: 
    # grab all links 
    res = pages_pool.imap_unordered(deco_process_people, pages, chunksize=1) 

    pages_done += pages 
    pages = [] 

    for new_users,new_pages in res: 
     users.update(new_users) 
     profile_tasks = [ (new_users[i]['link'],i) for i in new_users ] 
     # enqueue grabbed links for parsing 
     profiles_pool.map_async(deco_process_profiles, 
           profile_tasks, chunksize=2, 
           callback=profile_update_callback) 
     # i dont need a result of map_async actually 
     # callback will apply parsed data to users dict 
     # users dict is an instance of Manager.dict() 

     for p in new_pages: 
      if p not in pages_done and p not in pages: 
       pages.append(p) 

    # we need more than 900 pages to be parsed for bug occurrence 
    #if len(pages) == 0: 
    if len(pages_done) > 900: 
     break 


# 
# closing other pools 
# 

# ---- the last printed string: 
print 'Closing profiles pool', 
sys.stdout.flush() 
profiles_pool.close() 
profiles_pool.join() 
print 'closed' 

我想這個問題是在池隊列錯誤打開任務計算,但我不舒爾不能檢查這一點 - IDK的如何獲得任務隊列長度。

它可能是什麼,以及首先看什麼?

+0

另外,我注意到:字符串,掛起是'profiles_pool.join()'。 – 2012-03-19 14:42:54

回答

1

我發現了一個錯誤的理由:「加入多處理池對象的方法掛起如果pool.map的迭代參數爲空」

http://bugs.python.org/issue12157

+0

啊哈,那肯定是吧。您可以從那裏應用修補程序,也可以在調用map_async之前使用'if profile_tasks:'來解決此問題。 – torek 2012-03-19 17:42:03

1

最明顯的問題是pages_done是一個同步的Manager.list對象(因此每個進程都可以自動訪問它),但是當pages作爲一個這樣的對象啓動時,它很快成爲一個普通的un(多)處理列表:

pages_done += pages 
pages = [] 

第二引述線重新綁定pages到一個新的,空的普通列表。

即使您在第二行刪除了所有pages元素(而不是重新分配賦值),您可能會遇到(例如)pages中有A,B和C的競爭第一行有+=,但第二行已成爲A,B,C和D.

快速解決方法是一次性取下pages,然後逐個放入pages_done(效率不高)。儘管這些可能不是共享數據結構可能會更好;它看起來不像他們需要的,在引用的代碼中(我假設一些沒有引號的代碼依賴於它 - 因爲否則重新綁定pages無論如何都是紅鯡魚!)。

+0

謝謝,我修復了成爲列表的'網頁'的錯誤。但是那個主要的'While True'只在一個(主)線程中運行,所以我想它應該沒問題。但主要錯誤仍然存​​在。 – 2012-03-19 14:28:35