python:使用多处理时访问变量的问题

时间:2015-04-22 10:03:32

标签: python class python-2.7 multiprocessing python-multiprocessing

我是python中多处理概念的新手,当我尝试在我的代码中包含多处理时,我遇到了访问变量的问题。对不起,如果我听起来天真,但我只是想不通。以下是我的方案的简单版本。

YourTab.ResumeLayout(false);

当我运行它时,它运行良好并给出输出:

class Data:
    def __init__(self):
        self.data = "data"
    def datameth(self):
        print self.data
        print mainvar

class First:
    def __init__(self):
        self.first = "first"
    def firstmeth(self):
        d = Data()
        d.datameth()
        print self.first

def mymethod():
    f = First()
    f.firstmeth()

if __name__ == '__main__':
    mainvar = "mainvar"
    mymethod()

但是当我尝试将data mainvar first 作为一个过程运行时

mymethod()

我收到这样的错误:

from multiprocessing import Process
class Data:
    def __init__(self):
        self.data = "data"
    def datameth(self):
        print self.data
        print mainvar

class First:
    def __init__(self):
        self.first = "first"
    def firstmeth(self):
        d = Data()
        #print mainvar
        d.datameth()
        print self.first


def mymethod():
    f = First()
    f.firstmeth()

if __name__ == '__main__':
    mainvar = "mainvar"
    #mymethod()
    p = Process(target = mymethod)
    p.start()

关键是,我无法从NameError: global name 'mainvar' is not defined 类或mainvar类中访问First。 我在这里缺少什么?

编辑: 实际上,在我的实际场景中,它不仅仅是声明mainvar,它是经过一些处理后的方法的返回值。

Data

编辑2: 正如@dciriello在评论中提到的,它在Linux中运行良好,但在Windows中运行良好:(

3 个答案:

答案 0 :(得分:4)

这是Windows的限制,因为它不支持fork。当子进程在Linux中分叉时,它会获得父进程状态的写时复制副本,因此您在mainvar内定义的if __name__ == "__main__":将存在。但是,在Windows上,子进程'通过重新导入程序的__main__模块来创建state。这意味着mainvar在孩子中不存在,因为它只在if __name__ == "__main__"后卫中创建。因此,如果您需要在子进程中访问mainvar,那么您唯一的选择是将其显式传递给子进程,作为mymethod构造函数中Process的参数:

mainvar = "whatever"
p = Process(target=mymethod, args=(mainvar,))

multiprocessing docs中提到了这种最佳做法:

  

明确将资源传递给子流程

     

在Unix上,子进程可以使用在a中创建的共享资源   使用全局资源的父进程。但是,最好通过   该对象作为子进程的构造函数的参数。

     

除了使代码(可能)与Windows兼容之外   只要子进程还活着就可以确保   对象不会在父进程中进行垃圾回收。

请注意大胆的部分 - 虽然它没有完全拼写,但它有助于Windows兼容性的原因是因为它有助于避免您看到的确切问题。

section of the docs中也详细介绍了由于缺少fork导致的Windows限制:

  

全局变量

     

请记住,如果在子进程中运行的代码尝试访问a   全局变量,然后它看到的值(如果有的话)可能不一样   作为Process.start时父进程中的值   调用。

     

但是,只是模块级常量的全局变量会导致   没问题。

注意"如果有的话#34;。因为你的全局变量是在if __name__ == "__main__":守卫内宣布的,所以它甚至不会出现在孩子身上。

答案 1 :(得分:1)

操作系统不允许进程轻松共享变量。如果他们愿意的话,那么每个流程都可以从任何其他流程中窃取数据,而您永远不会想要这样(例如,当您在网络浏览器中输入信用卡详细信息时)。

因此,当您使用multiprocessing模块时,您必须使用特殊工具在ValueArray等各个流程之间共享变量(a.k.a“州”)。 See the documentation了解详情。

答案 2 :(得分:0)

你在错误的地方使用'mainvar',

尝试以下:

from multiprocessing import Process

mainvar = "mainvar"
class Data:
    def __init__(self):
        self.data = "data"
    def datameth(self):
        print self.data
        print mainvar

class First:
    def __init__(self):
        self.first = "first"
    def firstmeth(self):
        d = Data()
        #print mainvar
        d.datameth()
        print self.first


def mymethod():
    f = First()
    f.firstmeth()

if __name__ == '__main__':
    #mainvar = "mainvar"
    #mymethod()
    p = Process(target = mymethod)
    p.start()