我有一个多处理脚本,它像这样循环遍历字典:

jobs = []
for key, val in datadict.items():
    jobs.append(pool.apply_async(worker, (val))

pool.close()
pool.join()


然后jobs是结果对象的列表,(在其中调用get()将给出数据列表)

我想格式化结果,以便它们是与输入字典具有相同键和顺序的字典。

我想在所有工作完成后就简单地这样做:

result = {key: jobs[key].get() for key, val in datadict}


之所以有效,是因为datadict中的键是整数(因此可用于索引作业列表)。
但是后来我想到,也许所得到的工作清单不一定按相同的顺序排列(创建时)-这是真的吗? (我希望订单会变得混乱,因为一个过程可能比另一个过程更快完成)

因此,我决定将keydatadict传递给worker函数,并再次将其作为结果返回给元组。因此,调用jobs[index].get()将返回一个元组,其中第一个值是键(刚通过函数传递),第二个值是实际结果

然后,我可以像这样创建字典:

result = dict([job.get() for job in jobs])


所以最终的脚本是:

def worker(val, key):
    res = "Do something to val"
    return (key, res)

if __name__ == "__main__":
    jobs = []
    for key, val in datadict.items():
        jobs.append(pool.apply_async(worker, (val, key))

    pool.close()
    pool.join()

    result = dict([job.get() for job in jobs])


但这是最好的方法吗?有几点困扰我:


到目前为止,jobs列表的结果顺序已与输入顺序匹配
通过函数传递值似乎有点愚蠢(即不执行任何操作)

最佳答案

显式排序datadict字典键,然后对其进行迭代。

import multiprocessing

def worker(val):
    res = "Do something to val {}".format(val)
    return res

if __name__ == "__main__":
    datadict = {1: 'val1', 2: 'val2', 0: 'val0'}
    jobs = []
    pool = multiprocessing.Pool()
    for key in sorted(datadict): # <------------
        jobs.append(pool.apply_async(worker, (datadict[key],)))
    pool.close()
    pool.join()
    result = [job.get() for job in jobs]
    print(result)
    # ['Do something to val 0', 'Do something to val 1', 'Do something to val 2']


顺便说一句,如果worker仅接受一个参数,则可以使用Pool.map

if __name__ == "__main__":
    datadict = {1: 'val1', 2: 'val2', 0: 'val0'}
    jobs = []
    pool = multiprocessing.Pool()
    result = pool.map(worker, sorted(datadict)) # <---
    pool.close()
    pool.join()

关于python - 从多处理中收集结果时确保正确的顺序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22038193/

10-09 08:04
查看更多