0

我有一个我正在多处理中处理的元素列表apply_async任务中处理这些元素,并使用 manager dict 中的一个键逐个更新处理的元素,我想在其上映射整个列表。

我尝试了以下代码:

#!/usr/bin/python

from multiprocessing import Pool, Manager

def spammer_task(d, my_list):
    #Initialize manager dict
    d['task'] = {
        'processed_list': []
    }

    for ele in my_list:
        #process here
        d['task']['processed_list'].append(ele)

    return

p = Pool()
m = Manager()
d = m.dict()

my_list = ["one", "two", "three"]

p.apply_async(spammer_task (d, my_list))
print d

最后,它只是在 dict 中发布空列表。输出:

{'task': {'processed_list': []}}

现在经过一番研究,我知道 manager dict 中的元素变得不可变,所以你必须用新数据重新初始化整个 dict 才能更新它。所以我尝试了以下代码,它给出了一个奇怪的错误。

#!/usr/bin/python

from multiprocessing import Pool, Manager

def spammer_task(d, my_list):
    #Initialize manager dict
    d['task'] = {
        'processed_list': []
    }

    for ele in my_list:
        #process here
        old_list = d['task']['processed_list']
        new_list = old_list.append(ele)
        #Have to do it this way since elements inside a manager dict become
        #immutable so
        d['task'] = {
            'processed_list': new_list
        }

    return

p = Pool()
m = Manager()
d = m.dict()

my_list = ["one", "two", "three"]

p.apply_async(spammer_task (d, my_list))
print d

输出:

回溯(最后一次调用):文件“./a.py”,第 29 行,在 p.apply_async(spammer_task (d, my_list)) 文件“./a.py”,第 14 行,在 spammer_task new_list = old_list。 append(ele) AttributeError: 'NoneType' 对象没有属性 'append'

不知何故,它似​​乎附加None到我无法弄清楚原因的列表中。

4

2 回答 2

1

根据https://bugs.python.org/issue6766上的解决方案

以下代码通过复制整个任务字典然后修改它并重新复制它来修复它

#!/usr/bin/python

from multiprocessing import Pool, Manager

def spammer_task(d, my_list):
    #Initialize manager dict
    d['task'] = {
        'processed_list': []
    }

    for ele in my_list:
        #process here
        foo = d['task']
        foo['processed_list'].append(ele)
        d['task'] = foo
    return

p = Pool()
m = Manager()
d = m.dict()

my_list = ["one", "two", "three"]

p.apply_async(spammer_task (d, my_list))
print d

输出:

{'task': {'processed_list': ['one', 'two', 'three']}}

于 2016-08-01T18:02:26.630 回答
1

除了确保d打印时实际包含某些内容外,结果仍然是{'task': {'processed_list': ['one', 'two', 'three']}}

#!/usr/bin/python

from multiprocessing import Pool

def spammer_task(my_list):
    #Initialize manager dict
    out= {
        'processed_list': []
    }

    for ele in my_list:
        #process here
        out['processed_list'].append(ele)

    return 'task',out



my_list = ["one", "two", "three"]

if __name__=="__main__":

    p = Pool()
    d=dict(p.imap_unordered(spammer_task, [my_list])) #this line blocks until finished
    print d
于 2016-08-02T10:20:16.697 回答