简体   繁体   English

蟒蛇。 多处理池。 如何获得所有结果

[英]Python. Multiprocessing pool. How to obtain all results

Started to play with Python and stuck with one silly situation. 开始使用Python并遇到一种愚蠢的情况。 My function returns two values. 我的函数返回两个值。 Using MP I'd like to make execution faster. 使用MP我想使执行速度更快。

import time
import multiprocessing as mp

def foo(bar, baz):
    print("start")
    time.sleep(2)
    print("end")
    return bar, baz


if __name__ == '__main__':
    pool = mp.Pool(processes=4)

    ret = []
    i = 0
    while i < 4 :
        j = i + 1
        while j < 4 :
            results = [pool.apply_async(foo, args=(i, j))]
            j = j + 1
        i = i + 1

    output = [p.get() for p in results]
    print(output)

In the same time finally I want to get a list of returned values like [(0,1),(0,2),...]. 最后,我同时希望获得一个返回值的列表,例如[(0,1),(0,2),...]。 However I see only one pair instead. 但是我只看到一对。 Any idea how to change this code shortly to have all results and do not lost parallelism? 知道如何立即更改此代码以得到所有结果并且不丢失并行性吗? Thanks! 谢谢!

start
start
start
start
end
start
end
start
end
end
end
end
[(2, 3)]

You're overwriting your results list on each iteration, but you should be appending to it. 您将在每次迭代中覆盖results列表,但应将其追加。 This should do the trick: 这应该可以解决问题:

results = []
while i < 4 :
    j = i + 1
    while j < 4 :
        results.append(pool.apply_async(foo, args=(i, j)))
        j = j + 1
    i = i + 1

output = [p.get() for p in results]

DIAGNOSIS 诊断

Here's your code with a little debugging, and using for statements for readability: 这是经过一些调试的代码,并使用for语句以提高可读性:

for i in range(4):
    for j in range(i+1, 4):
        results = [pool.apply_async(foo, args=(i, j))]
        print("TRACE", results]

output = [p.get() for p in results]
print("FINAL", output)

Looking at the output, you can see the problem: although you made 6 distinct result collectors, result is merely the most recent at any given time. 查看输出,您会看到问题:尽管您制作了6个不同的结果收集器,但result只是在任何给定时间的最新result Thus, you need to collect them all. 因此,您需要收集它们全部。

Output: 输出:

TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b711390>]
TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b7114e0>]
TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b711588>]
TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b711630>]
TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b7116d8>]
start
TRACE [<multiprocessing.pool.ApplyResult object at 0x7faf4b711780>]
start
start
start
end
end
start
start
end
end
end
end
FINAL [(2, 3)]

SOLUTION

"Merely" use a nested-loop list comprehension to get the list of result applications you want: “仅”使用嵌套循环列表推导来获取所需结果应用程序的列表:

results = [pool.apply_async(foo, args=(i, j))
              for i in range(4)
                 for j in range(i+1, 4)
          ]
print("TRACE", results)

output = [p.get() for p in results]
print("FINAL", output)

Output: 输出:

TRACE [<multiprocessing.pool.ApplyResult object at 0x7f52af945390>, 
       <multiprocessing.pool.ApplyResult object at 0x7f52af945438>, 
       <multiprocessing.pool.ApplyResult object at 0x7f52af9454e0>, 
       <multiprocessing.pool.ApplyResult object at 0x7f52af945588>,  
       <multiprocessing.pool.ApplyResult object at 0x7f52af945630>, 
       <multiprocessing.pool.ApplyResult object at 0x7f52af9456d8>]
start
start
start
start
end
end
end
end
start
start
end
end
FINAL [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM