2

为什么这个代码

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)            

给出以下输出?

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

正如你可能猜到的那样,我希望得到所有 99,IN 和 OUT。但我不。为什么?我错过了什么?

4

3 回答 3

2

一旦你调用start()了你的对象,那个对象里面的东西就会在一个单独的进程中运行,并且使用那个类的方法来与它“通信”并不是最好的方法。您需要做的就是所谓的进程间通信(简称 IPC),并且有特殊的机制可以正确地进行。

对于 Python 的multiprocessing模块,进程之间有两种通信机制:PipeQueue. 我建议调查那些(例如这里)。

要在您的示例中使用该Pipe机制,您可以这样做(只是一个简单的说明):

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)

看看这里做了什么:我们创建 的父和子“端” Pipe,并将子端赋予您的对象。send()然后从用于将新值传达给对象的父进程,并recv()获取更新的值。同样,在您的对象内部(一个单独的进程,请记住)您反过来使用管道的另一端与父进程通信send()recv()

另外,我建议在进行任何其他初始化之前Process.__init__(self)调用您的类__init__方法。由于您是从中继承的,因此在您在自己的类中执行任何操作之前,确保引擎盖下的所有进程-y 内容都得到正确初始化是一个好主意。Process

希望这可以帮助。

于 2013-05-15T16:17:10.613 回答
1

问题是,一旦您开始第二个过程,您就会从 2 个不同的过程中进行打印。

父进程具有 bot 的原始实例,然后将值设置为 99。父进程正在打印 OUT,这就是打印值 99 的原因。

(新的)子进程以从 bot 对象复制的状态开始,就像您调用 multiprocessing 方法时一样start()。因此,它的状态为 0。您永远不会在子进程中调用 setVal,因此它的值保持为 0,并且 IN 打印 print 0。

如果您想在父进程和子进程之间共享这样的状态信息,请阅读以下内容: http: //docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes

于 2013-05-15T16:23:00.723 回答
0
bot = Bot() # creates a bot object in this process
bot.start() # creates an other process and creates a bot object there

这是两个不同的对象。如果你想看看如何在两个进程之间共享状态:http: //docs.python.org/2/library/multiprocessing.html#namespace-objects

或者在 DMH 提出的管道上:http: //docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes

于 2013-05-15T16:17:46.237 回答