Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class inheriting multiprocessing, trouble with accessing class members

In short, say I have the following:

import multiprocessing

class Worker(multiprocessing.Process):
    def __init__(self):
        multiprocessing.Process.__init__(self)
        print "Init"
        self.value = None

    def run(self):
        print "Running"
        self.value = 1

p = Worker()
p.start()
p.join()
print p.value

I'd expect the output to be:

Init
Running
1

Instead it is

Init
Running
None

Can someone explain to me why this is the case? What am I not understanding, and how should I go about doing it correctly?

Thanks.

like image 975
swalog Avatar asked Sep 25 '11 12:09

swalog


1 Answers

The moment you say p.start(), a separate process is forked off of the main process. All variable values are copied. So the main process has one copy of p, and the forked process has a separate copy of p. The Worker modifies the forked process's copy of p.value, but the main process's p.value still is None.

There are many ways to share objects between processes. In this case, perhaps the easiest way is to use a mp.Value:

import multiprocessing as mp

class Worker(mp.Process):
    def __init__(self):
        print "Init"
        mp.Process.__init__(self)
        self.num = mp.Value('d', 0.0)

    def run(self):
        print "Running"
        self.num.value = 1

p = Worker()
p.start()
p.join()
print p.num.value

Note that the mp.Value has a default value of 0.0. It can not be set to None.

like image 52
unutbu Avatar answered Sep 29 '22 12:09

unutbu