开始使用Python并遇到一种愚蠢的情况。 我的函数返回两个值。我希望使用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)
最后,我想同时获得一个返回值的列表,例如[(0,1),(0,2),...]。但是我只看到一对。知道如何立即更改此代码以得到所有结果并且不丢失并行性吗? 谢谢!
start
start
start
start
end
start
end
start
end
end
end
end
[(2, 3)]
答案 0 :(得分:1)
您在每次迭代中都将覆盖results
列表,但是您应该将其追加。这应该可以解决问题:
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]
答案 1 :(得分:1)
诊断
这是经过一些调试的代码,并使用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)
查看输出,您可以看到问题:尽管您制作了6个不同的结果收集器,但是result
只是在任何给定时间的最新收集器。您需要全部选拔。
输出:
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)]
解决方案
“仅”使用嵌套循环列表推导来获取所需的结果应用程序列表:
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)
输出:
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)]