max*_*max 8 python multiprocessing python-3.x python-multiprocessing
docs(python 3.4)解释说spawn
,"子进程只会继承运行进程对象run()
方法所需的那些资源".
但哪些对象是"必要的"?我读它的方式告诉我,从内部可以到达的所有对象run()
都是"必要的",包括传递args
给的参数Process.__init__
,加上存储在全局变量中的任何东西,以及在全局范围内定义的类,函数及其属性.但是,这是不正确的; 以下代码确认不会继承存储在全局变量中的对象:
# 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()
Run Code Online (Sandbox Code Playgroud)
是否有明确的规则说明哪些对象是继承的?
编辑:
要确认:在Ubuntu上运行它会产生相同的输出.(感谢@mata澄清,我忘添加global x
到main()
这种省略使我示例混淆;它也将影响结果,如果我是切换'spawn'
到'fork'
在Ubuntu下我现在加入global x
到上面的代码).
这与发送到生成的进程时类被pickle的方式有关.类的pickle版本并不真正包含其内部状态,而只包含模块和类的名称:
class A:
y = 0
pickle.dumps(A)
# b'\x80\x03c__main__\nA\nq\x00.'
Run Code Online (Sandbox Code Playgroud)
这里没有关于y
它的信息,它与类的引用相当.
当作为argumeht传递时,该类将在生成的进程中进行unpickled,如果需要g
,将导入其模块(此处__main__
)并返回对类的引用,因此在main
函数中对其进行的更改将不会影响它,因为if __name__ == "__main__"
块赢了不在子进程中执行.f
直接在其模块中使用该类,因此效果基本相同.
x
显示不同值的原因略有不同.您的f
函数将从模块中打印全局变量x
.在您的main()
函数中,您有另一个局部变量x
,因此x = 1
此处的设置不会影响x
两个进程中的模块级别.它被传递给g
作为参数,因此在这种情况下,它将使alays具有本地值1.
归档时间: |
|
查看次数: |
3672 次 |
最近记录: |