Python 在多处理中传递字典进行处理
我有一个类,其中包含(大量)不同的属性,包括一些字典。当我将类的实例传递到新进程时,所有数值似乎都正确传递,但类对象中的任何字典都被清空。
这是我编写的一个简单测试,它演示了我的问题:
from multiprocessing import Process
class State:
a = 0
b = {}
def f(s, i):
print "f:", s.a, s.b
def main():
state = State()
state.a = 11
state.b['testing'] = 12
print "Main:", state.a, state.b
ps = []
for i in range(1):
p = Process(target=f, args=(state, i))
p.start() # Do the work
ps.append(p)
for p in ps:
p.join()
if __name__ == '__main__':
main()
我期望输出是
Main: 11 {'testing': 12}
f: 11 {'testing': 12}
,但我得到
Main: 11 {'testing': 12}
f: 11 {}
I have a class that contains a (large) number of different properties, including a few dictionaries. When I pass an instance of the class through to a new process, all of the numeric values seem to get passed in correctly, but any dictionaries that were in the class object get emptied.
Here's a simple test I cooked up that demonstrates my problem:
from multiprocessing import Process
class State:
a = 0
b = {}
def f(s, i):
print "f:", s.a, s.b
def main():
state = State()
state.a = 11
state.b['testing'] = 12
print "Main:", state.a, state.b
ps = []
for i in range(1):
p = Process(target=f, args=(state, i))
p.start() # Do the work
ps.append(p)
for p in ps:
p.join()
if __name__ == '__main__':
main()
I expect the output to be
Main: 11 {'testing': 12}
f: 11 {'testing': 12}
but instead I get
Main: 11 {'testing': 12}
f: 11 {}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
多处理模块的文档中清楚地描述了该问题:Windows 缺少
fork()
系统调用,因此在 Windows 上,模块源代码会在每个进程开始时重新评估,从而确定当前状态未保存。 (在基于 un*x 的系统上,包括 OSX,进程是使用 fork 实现的,并且状态被保留)请注意,我正在谈论整个 python 模块的状态。
您保持状态的方式是错误的:
State
类的a
和b
成员是类范围的“静态”成员,它们是不是State
对象实例的一部分。当执行state.a = 11
时,您正在修改State
类,而不是该类的实例。如果
a
和b
是State
类的实例成员,那么您的代码会正常工作:然后传递
state 实例到一个新进程,将按预期正确传递值。
the problem is clearly described in the documentation for the multiprocessing module: windows lacks a
fork()
system call, so on windows, the module source code gets reevaluated at the start of each process, thus the current state is not preserved. (on un*x based system, including OSX, Process is implemented using a fork, and the state is preserved)note that i am talking about the state of the whole python module.
your way of holding a state is wrong: the
a
andb
members of theState
class are class-wide 'static' members, they are not part of an instance of aState
object. when doingstate.a = 11
, you are modifying theState
class, not an instance of the class.your code would have worked fine if
a
andb
had been instance members of theState
class:then, passing the
state
instance to a new Process, would have correctly passed the value as expected.我最终通过除了状态之外还显式传递字典来解决这个问题。例如
p = Process(target=f, args=(state, i, state.b))
I ended up working around this problem by passing the dictionaries in explicitly in addition to the state. e.g.
p = Process(target=f, args=(state, i, state.b))