[英]Changing object properties in python multiprocessing
考虑以下对象:
class Item(object):
def __init__(self):
self.c = 0
def increase(self):
S.increase(self)
class S(object):
@staticmethod
def increase(item):
item.c += 1
这反映了我当前的情况,S是某些库类,Item收集和组织数据以及数据处理过程。 现在,我想并行化工作,为此,我使用了python multiprocessing模块:
from multiprocessing import Process
l= [Item() for i in range(5)]
for i in l:
Process(target=i.increase).start()
结果不是我所期望的:
[i.c for i in l]
[0, 0, 0, 0, 0]
我要去哪里错了?
您期待着您的变种者, S
类的静态方法increase
(从类item
的非静态increase
中调用)可以调整每个ic
字段,而且确实如此。 问题不在于静态方法,而在于multiprocessing
的内部设计。
multiprocessing
程序包通过运行多个单独的Python实例来工作。 在类似Unix的系统上,它使用fork
,这使此操作更加容易。 在类似Windows的系统上,它会产生自己的新副本。 无论哪种方式,这都施加了Python文档中描述的所有稍微奇怪的限制: v2和v3 。 (注意:下面的其余链接都指向Python2文档,因为那是我仍然打开的页面。Python2和Python3的限制几乎相同。)
在这种特定情况下,每个Process
调用都会复制对象i
,并将该副本发送到新进程。 该过程将修改副本,但对原件没有影响。
要解决此问题,您可以将修改后的对象(例如,通过Queue()或Pipe()实例)发送回去,或将这些对象放入共享内存中 。 回传技术更简单,更容易编程,并且自动执行大多数必要的同步(但请注意有关在使用Process实例的join
(包括隐式)确保收集所有结果的注意事项)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.