Issue with setting value for Python class inherited from multiprocessing.Process

别来无恙 提交于 2019-12-06 10:50:23

问题


Why this code

import multiprocessing
import time

class Bot(multiprocessing.Process):
    def __init__(self):        
        self.val = 0
        multiprocessing.Process.__init__(self)

    def setVal(self):
        self.val = 99

    def run(self):        
        while True:            
            print 'IN: ', self.val
            time.sleep(2)

if __name__ == '__main__':  
    bot = Bot()
    bot.start()
    bot.setVal()
    while True:
        print 'OUT: ', bot.val
        time.sleep(2)            

gives following output?

OUT:  99
IN:  0
OUT:  99
IN:  0
OUT:  99
IN:  0
OUT:  99
IN:  0
OUT:  99
IN:  0
OUT:  99
IN:  0
...

As you may guess i expect to get all 99, IN and OUT. But i do not. Why? What am i missing?


回答1:


The problem is that once you start the second process, you are printing from 2 different processes.

The parent process has the original instance of bot, with the value then set to 99. The parent process is printing OUT which is why you get the value 99 printed.

The (new) subprocess starts with state copied from the bot object as it was when you called the multiprocessing method start(). Because of this, it has a state of 0. You never call setVal in the subprocess and so it's value remains 0, and the IN prints print 0.

If you want to share state information like this between the parent process and the subprocess, have a read of this: http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes




回答2:


Once you've called start() on your object, the stuff inside that object is running in a separate process, and using methods of that class to "communicate" with it are not really the best way. What you need to do is called inter-process communication (IPC for short) and there is special machinery for doing it correctly.

For Python's multiprocessing module there are two mechanisms for communicating between processes: Pipe and Queue. I would suggest looking into those (e.g. here).

To use the Pipe mechanism in your example, you might do it this way (just a quick illustration) :

class Bot(multiprocessing.Process):
    def __init__(self, pipe):
        multiprocessing.Process.__init__(self)
        self.val = 0
        self.ipcPipe = pipe

    def run(self):
        while True: 
            newData = self.ipcPipe.recv()
            self.val = newData[0]
            print 'IN: ', self.val
            self.ipcPipe.send([self.val])
            time.sleep(2)

if __name__ == '__main__': 
    parent_conn, child_conn = multiprocessing.Pipe()
    bot = Bot(child_conn)
    bot.start()
    value = 0
    while True:
        value += 1
        parent_conn.send([value])
        outVal = parent_conn.recv()
        print 'OUT: ', outVal[0]
        time.sleep(2)

See what's been done here: We create parent and child "ends" of the Pipe, and give the child end to your object. Then from the parent process you use send() to communicate a new value to the object, and recv() to get an updated value back. Likewise inside your object (a separate process, remember) you conversely use send() and recv() on the pipe's other end to communicate with the parent process.

Also, I would recommend calling Process.__init__(self) in your class __init__ method before doing any other initialization. Since you're inheriting from Process it's a good idea to make sure all the process-y stuff under the hood gets initialized correctly before you do anything in your own class.

Hope this helps.




回答3:


bot = Bot() # creates a bot object in this process
bot.start() # creates an other process and creates a bot object there

These are two different objects. If you want to have a look at how to share state between two processes: http://docs.python.org/2/library/multiprocessing.html#namespace-objects

Or at the pipes also proposed by DMH: http://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes



来源:https://stackoverflow.com/questions/16569175/issue-with-setting-value-for-python-class-inherited-from-multiprocessing-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!