不能使用Python3中的multiprocessing.Process对象更改类变量

时间:2015-09-19 09:31:04

标签: python class variables python-3.x multiprocessing

如果我用类变量编写一个类,生成两个类对象,并使用两个对象之一的方法更改类变量的值,那么类变量值当然也会更改为另一个对象。这就是我在代码中的意思:

class DemoClass:
    ClassVariable = False

    def __init__(self):
        pass

    def do(self):
        print(DemoClass.ClassVariable)
        DemoClass.ClassVariable = True


class1 = DemoClass()
class1.do()  # False
class2 = DemoClass()
class2.do()  # True

但是,如果我对multiprocessing.Process执行相同操作,则不起作用。类变量值仅对更改它的对象进行更改:

import multiprocessing

class DemoProcess(multiprocessing.Process):
    ClassVariable = False

    def __init__(self):
        multiprocessing.Process.__init__(self)

    def run(self):
        print(DemoProcess.ClassVariable)
        DemoProcess.ClassVariable = True
        print(DemoProcess.ClassVariable)


if __name__ == '__main__':
    process_list = []
    p1 = DemoProcess()
    process_list.append(p1)
    p1.start()  # False True
    p2 = DemoProcess()
    process_list.append(p2)
    p2.start()  # False True; should be: True True

    for p in process_list:
        p.join()

代码的行为就像每个进程生成一个新的类变量一样。我做错了吗?

1 个答案:

答案 0 :(得分:2)

在我原始问题的评论者的帮助下,我得出结论,我还不知道过程是如何运作的。

每个DemoProcess.start()都会创建一个新的Process无法与其他进程共享其类变量。

我通过使用Mike McKerns在评论中提出的multprocessing.Value对象解决了这个问题。可以与多个进程共享此对象的值。

import multiprocessing

class DemoProcess(multiprocessing.Process):

    def __init__(self, class_variable):
        multiprocessing.Process.__init__(self)
        self.class_variable = class_variable

    def run(self):
        print(self.class_variable.value)
        with self.class_variable.get_lock():
            self.class_variable.value = True
        print(self.class_variable.value)


if __name__ == '__main__':
    ClassVariable = multiprocessing.Value('b', False)

    process_list = []
    p1 = DemoProcess(ClassVariable)
    process_list.append(p1)
    p1.start()  # Output: 0 1
    p2 = DemoProcess(ClassVariable)
    process_list.append(p2)
    p2.start()  # Output: 1 1

    for p in process_list:
        p.join()