Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理映射异步挂起_Python_Multiprocessing_Pool - Fatal编程技术网

Python多处理映射异步挂起

Python多处理映射异步挂起,python,multiprocessing,pool,Python,Multiprocessing,Pool,我[可能]在关闭解析器中的进程池时遇到了一些问题。当所有任务完成时,它挂起并且什么也不做,cpu使用率约为1% 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: # g

我[可能]在关闭解析器中的进程池时遇到了一些问题。当所有任务完成时,它挂起并且什么也不做,cpu使用率约为1%

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如何获取任务队列长度


它可以是什么,以及首先看哪里?

最明显的问题是,
pages\u done
是一个同步的Manager.list对象(因此每个进程都可以以原子方式访问它),但是当
pages
以这样的方式开始时,它很快就会变成一个普通的未(多)处理列表:

pages_done += pages
pages = []
第二行引号将
页面重新绑定到新的空普通列表中

即使您删除了第二行
页面
的所有元素(而不是执行重新绑定任务),您也可能会遇到这样一场竞赛:当您在第一行执行
+=
时,
页面
中有a、B和C,但在第二行变成了a、B、C和D


一个快速解决方法是将项目从
页面上一次取下一个,然后将它们放入
页面中,一次一个(效率不高)。不过,最好不要让这些数据结构共享;在带引号的代码中(我假设一些不带引号的代码依赖于它,因为否则,
页面的重新绑定无论如何都是一个麻烦!)。

我发现了一个错误的原因:“如果Pool.map的iterable参数为空,则多处理池对象的join方法将挂起”


谢谢,我已经修复了“页面”变成列表的错误。但是主“While True”只在一个(主)线程中运行,所以我想应该可以。但是主要的bug仍然存在。另外,我必须注意:挂起的字符串是
profiles\u pool.join()
。啊哈,肯定就是它了。您可以从那里应用修复程序,或者在调用
map\u async
之前使用
if profile\u tasks:
解决它。