Python中fork启动的子进程修改的变量无法在父对象中同步
为什么fork启动的子进程修改的变量在父进程中不可见?
你在Python中定义了父类和子类,通过multiprocessing.Process以fork方式启动子进程修改子类变量,但父进程中看不到变量的修改。示例代码如下:
import multiprocessing from multiprocessing import Queue, Process import time class Parent: def __init__(self): print(multiprocessing.get_start_method()) self.child = Child() def start(self): self.child.start_child() def print_child_variable(self): print('Parent: Child Variable: ' + str(self.child.some_variable)) class Child: def __init__(self): self.some_variable = None self.status = False def start_child(self): self.status = True do_something_process = Process(target=self.do_something) do_something_process.start() def do_something(self): self.some_variable = True print('Child: some variable after changing: ' + str(self.some_variable)) def print_some_variable(self): print('Child: some variable: ' + str(self.some_variable)) if __name__ == '__main__': parent = Parent() parent.print_child_variable() time.sleep(1) parent.start() parent.print_child_variable() time.sleep(1) parent.print_child_variable() time.sleep(1) parent.child.print_some_variable()
运行输出:
fork Parent: Child Variable None Parent: Child Variable None Child: some variable after changing True Parent: Child Variable None Child: some variable None
原因解释
核心问题在于fork模式的内存隔离机制:
- 当用fork启动子进程时,操作系统会为子进程创建父进程内存空间的副本(采用写时复制策略:初始时共享内存,只有当子进程修改数据时才会复制对应内存页,变成子进程私有)。
- 你启动的子进程里的
Child对象,是父进程中Child对象的独立副本。子进程在do_something里修改self.some_variable,只是修改了这个私有副本里的变量,完全不会影响父进程中原来的Child对象的变量。 - 父进程里调用
parent.print_child_variable()或者parent.child.print_some_variable(),访问的都是父进程自己内存里的Child对象,自然看不到子进程里的修改。
如果要实现父子进程间的变量同步,需要使用multiprocessing模块提供的共享内存工具,比如Value、Array,或者用队列(Queue)、管道(Pipe)来传递数据。
内容的提问来源于stack exchange,提问作者Ignacio
相关产品推荐
相关产品推荐

