我得到了一个在多处理中运行的程序。我想要一个带有印刷品的进度系统。
这就是我想出的:
import multiprocessing as mp
import os
global counter
global size
def f(x):
global counter
global size
print ("{} / {}".format(counter, size))
counter += 1
return x**2
size = 4
counter = 1
result = list()
for x in [1,2,3,4]:
result.append(f(x))
这个有效。但是,如果将底部替换为:
with mp.Pool(processes = 2) as p:
p.starmap(f, [1,2,3,4])
其实不然。我不明白为什么,任何人都可以帮助启动和运行它吗?谢谢:)
注意:这当然是一个虚拟的例子。
编辑:
好的,您的解决方案出现了新问题。我举个例子:
fix1 = 1
fix2 = 2
dynamic = [1,2,3,4,5]
def f(x, y, z):
return x**2 + y + z
size = len(dynamic)
counter = 1
with mp.Pool(processes = 2) as p:
for output in p.starmap(f, [(x, fix1, fix2) for x in dynamic]):
print ("{} / {}".format(counter, size))
counter += 1
这个有效,但在最后完成所有打印。
with mp.Pool(processes = 2) as p:
for output in p.imap_unordered(f, [(x, fix1, fix2) for x in dynamic]):
print ("{} / {}".format(counter, size))
counter += 1
这个不起作用,并说 f(( 缺少 2 个必需的位置参数 fix1 和 fix2。
知道为什么我会有这种行为吗?
注意:我在窗口上运行。
在像 Linux 这样的分叉系统上,子进程共享父内存空间的写入时复制视图。如果一端更新内存,它将获得更改页面的私有副本。在其他系统上,将创建一个新进程并执行一个新的 python。无论哪种情况,双方都看不到对方所做的改变。这意味着每个人都在更新自己的count
私人副本,并且看不到其他人所做的添加。
为了使事情变得复杂,stdout
不同步。如果工作人员打印,您可能会收到乱码消息。
另一种方法是在结果返回到父池时对结果进行计数。父级跟踪计数,父级是唯一的打印者。如果您不关心返回数据的顺序,那么imap_unordered
将非常适合您。
import multiprocessing as mp
def f(x):
return x**2
data = [1,2,3,4]
result = []
with mp.Pool(processes = 2) as p:
for val in p.imap_unordered(f, data):
result.append(val)
print("progress", len(result)/len(data))