Reputation: 191
I'm trying to change a class field using it's method, but when the method is put into it doesn't work.
from multiprocessing import Process
class Multi:
def __init__(self):
self.x = 20
def loop(self,):
for i in range(1,100):
self.x = i
M = Multi()
p = Process(target=M.loop)
p.start()
After running this program M.x is still 20. How is that possible?
Upvotes: 17
Views: 33004
Reputation: 7872
First, you want to use join
, which waits for the process to finish before continuing through the rest of the code.
Second, when you use multiprocess
, it creates a new instance of M
for every Process
. You can see this when printing self
within loop
class Multi:
def __init__(self):
self.x = 20
def loop(self):
print(self, 'loop')
for i in range(1, 100):
self.x = i
if __name__ == '__main__':
M = Multi()
print(M, 'main 1')
p = Process(target=M.loop)
p.start()
p.join()
print(M, 'main 2')
>>> <__main__.Multi object at 0x000001E19015CCC0> main 1
>>> <__mp_main__.Multi object at 0x00000246B3614E10> loop
>>> <__main__.Multi object at 0x000001E19015CCC0> main 2
Because of that, the value of x
is never updated in the original class.
Fortunately, there is a Value object that you can use that handles this. This creates a shared memory object that can be modified through the processes
from multiprocessing import Process, Value
class Multi:
def __init__(self):
self.x = Value('i', 20)
def loop(self):
for i in range(1, 100):
self.x.value = i
if __name__ == '__main__':
M = Multi()
p = Process(target=M.loop)
p.start()
p.join()
print(int(M.x.value))
>> 99
Upvotes: 22