Barty
Barty

Reputation: 191

Python multiprocessing class methods

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

Answers (1)

Wondercricket
Wondercricket

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

Related Questions