I have a parent class in Python that can start a process in a child class. The child class has a multiprocessing.Process that changes some variables. I would expect changes to be visible for the parent class since the object is created there, but somehow, the variables are not shared. The process is started as a fork.
Here is an example code:
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()
The output:
fork
Parent: Child Variable None
Parent: Child Variable None
Child: some variable after chaging True
Parent: Child Variable None
Child: some variable None
I would expect that after the change, the variable some_variable will be true even if checked from the parent object. Can anyone help me understand what is going on?
Here is how I would create an attribute that can represent boolean values and be sharable across multiple processes. See multiprocessing.Value
.
from multiprocessing import Process, get_start_method, Value
import ctypes
import time
class Parent:
def __init__(self):
print(get_start_method())
self.child = Child()
def start(self):
self.child.start_child()
def print_child_variable(self):
print('Parent: Child Variable:', self.child.some_variable.value)
class Child:
def __init__(self):
# This Value instance can only have values True and False:
self.some_variable = Value(ctypes.c_bool, False)
def start_child(self):
do_something_process = Process(target=self.do_something)
do_something_process.start()
def do_something(self):
self.some_variable.value = True
print('Child: some variable after changing:', self.some_variable.value)
def print_some_variable(self):
print('Child: some variable:', self.some_variable.value)
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()
Prints:
fork
Parent: Child Variable: False
Parent: Child Variable: False
Child: some variable after changing: True
Parent: Child Variable: True
Child: some variable: True