Python 在多处理中传递字典进行处理

发布于 2024-12-03 12:54:14 字数 741 浏览 2 评论 0原文

我有一个类,其中包含(大量)不同的属性,包括一些字典。当我将类的实例传递到新进程时,所有数值似乎都正确传递,但类对象中的任何字典都被清空。

这是我编写的一个简单测试,它演示了我的问题:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰つ倒转 2024-12-10 12:54:14

多处理模块的文档中清楚地描述了该问题:Windows 缺少 fork() 系统调用,因此在 Windows 上,模块源代码会在每个进程开始时重新评估,从而确定当前状态未保存。 (在基于 un*x 的系统上,包括 OSX,进程是使用 fork 实现的,并且状态被保留)

请注意,我正在谈论整个 python 模块的状态。

您保持状态的方式是错误的:State类的ab成员是类范围的“静态”成员,它们是不是 State 对象实例的一部分。当执行 state.a = 11 时,您正在修改 State 类,而不是该类的实例。

如果 abState 类的实例成员,那么您的代码会正常工作:

class State(object):
    def __init__(self)
        self.a = 0
        self.b = {}

然后传递 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 and b members of the State class are class-wide 'static' members, they are not part of an instance of a State object. when doing state.a = 11, you are modifying the State class, not an instance of the class.

your code would have worked fine if a and b had been instance members of the State class:

class State(object):
    def __init__(self)
        self.a = 0
        self.b = {}

then, passing the state instance to a new Process, would have correctly passed the value as expected.

泪是无色的血 2024-12-10 12:54:14

我最终通过除了状态之外还显式传递字典来解决这个问题。例如

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))

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文