![](/img/trans.png)
[英]Spawn multiprocessing.Process under different python executable with own path
[英]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.