繁体   English   中英

multiprocessing.Process(使用spawn方法):继承了哪些对象?

[英]multiprocessing.Process (with spawn method): which objects are inherited?

docs(python 3.4)解释说,使用spawn ,“子进程将仅继承运行进程对象的run()方法所需的那些资源”。

但是哪些对象是“必需的”? 我的阅读方式告诉我,从run()内部可以访问的所有对象都是“必需的”,包括以args传递给Process.__init__ args ,以及存储在全局变量以及类,函数中的任何东西在全局范围及其属性中定义。 但是,这是不正确的。 以下代码确认未继承全局变量中存储的对象:

# running under python 3.4 / Windows
# but behaves the same under Unix
import multiprocessing as mp

x = 0
class A:
    y = 0

def f():
    print(x) # 0
    print(A.y) # 0

def g(x, A):
    print(x) # 1
    print(A.y) # 0; really, not even args are inherited?

def main():
    global x
    x = 1
    A.y = 1
    p = mp.Process(target = f)
    p.start()
    q = mp.Process(target = g, args = (x, A))
    q.start()


if __name__=="__main__":
    mp.set_start_method('spawn')
    main()

是否有明确的规则规定要继承哪些对象?

编辑:

确认一下:在Ubuntu上运行它会产生相同的输出。 (感谢@mata澄清了我忘记在main()添加了global x 。这一遗漏使我的示例感到困惑;如果在Ubuntu下将'spawn'切换为'fork' ,也会影响结果。我现在添加了global x到上面的代码。)

这与将类发送到派生的Process时的腌制方式有关。 类的腌制版本实际上并不包含其内部状态,而仅包含模块和类的名称:

class A:
   y = 0

pickle.dumps(A)
# b'\x80\x03c__main__\nA\nq\x00.'

这里没有关于y信息,它与对该类的引用相当。

当作为argumeht传递给g ,该类将在生成的进程中被取消选择,该类将在必要时导入其模块(在这里__main__ )并返回对该类的引用,因此,对您在main函数中进行的更改不会对它产生影响if __name__ == "__main__"块将不会在子if __name__ == "__main__"中执行。 f直接在其模块中使用该类,因此效果基本相同。

x显示不同值的原因略有不同。 您的f函数将从模块中打印全局变量x main()函数中,您还有另一个局部变量x ,因此在此处设置x = 1不会影响两个进程中的模块级别x 它作为参数传递给g ,因此在这种情况下,它将局部值为1。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM