python multiprocess.Pool 在标准输出中按顺序显示结果

python multiprocess.Pool show results in order in stdout

在 multiprocessing.Pool 中,我试图以相同的顺序显示我的版画。

from multiprocessing import Pool
import time
def func(arg):
    time.sleep(0.001)
    print(arg, end=" ")

proc_pool = Pool(4)
proc_pool.map(func, range(30))

输出是:0 1 8 9 10 11 14 15 6 7 16 17 4 5 12 13 18 19 2 3 或类似的。顺序不对0 1 2 3 ...

我知道 imap 可以提供更好的排序...但它仍然不是我想要的。我可以覆盖打印功能以将其保存到一个变量中并一次打印它们 - 但我更愿意在它们完成时立即显示它们 - 而不是在全部完成时显示它们。

鉴于 Pool 在工作进程(由操作系统调度)之间分发列表的元素,您无法保证输出顺序为map.

你可能做的最好的事情(使用 map)是将输入更改为元组列表 (sequence_number, data),使用辅助函数 return (sequence_number, result) 然后按 sequence_number.

排序

如果您想在项目完成后立即开始处理,请使用 imapimap_unordered。使用 imap 将保留与输入可迭代对象相同的顺序。如果您对 (sequence_number, result) 元组使用与 imap 相同的技巧,您可以将结果保存在列表中,并在得到一个没有间隙的序列后打印它们。

澄清 - OP 正在寻求在流程完成后立即获得订单(而不是等待所有流程完成)。 Map 确实保证输出顺序 - 但您需要等待所有过程完成。

这是另一个强调这一点的讨论 -

这是编辑后的代码,以及对像我这样可能会感到困惑的人来说两者之间的区别结果。

from multiprocessing import Pool
import time


def func(arg):
   time.sleep(0.001)
   print("process order: "+str(arg))
   return arg
if __name__=='__main__':
   proc_pool = Pool(4)
   results = proc_pool.map(func, range(30))
   proc_pool.close()
   proc_pool.join()

   for a in results:
      print("output order"+str(a))` 

结果是:

process order: 6
process order: 7
process order: 14

output order0
output order1
output order2
output order3
output order4
output order5
output order6
output order7
output order8
output order9
output order10
output order11
output order12
output order13
output order14
output order15
output order16
output order17
output order18
output order19
output order20
output order21
output order22
output order23
output order24
output order25
output order26
output order27
output order28
output order29