9

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.

swalog
  • 4,403
  • 3
  • 32
  • 60

1 Answers1

12

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.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • Thanks. It also seems like creating the num value within the constructor (as opposed to constructing it in main and passing it) also works fine. I'll leave the answer unaccepted for a little while (as I've heard is customary in SO). – swalog Sep 25 '11 at 12:21
  • You can use MangerPools for better type handling – Danish Bansal Jan 04 '23 at 05:27