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

匿名 (未验证) 提交于 2019-12-03 07:50:05

问题:

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



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