使用python更改线程中的对象值

时间:2013-08-14 08:08:14

标签: python multiprocessing

我是Python的新手,因此我可能会问一个简单的问题。

我正在使用Python编写多进程代码:

from multiprocessing import Process
from multiprocessing import Queue

class myClass(object):

    def __init__(self):
        self.__i = 0
        self.__name = 'rob'
        return

    def target_func(self, name, q):
        self.__name = name
        print 'Hello', self.__name
        self.__i += 1
        print self.__i
        q.put([self.__i, self.__name])
        return

    def name(self):
        return self.__name

    def i(self):
        return self.__i


if __name__ == '__main__':
    mc = myClass()

    q = Queue()

    p = Process(target = mc.target_func, args = ('bob', q,))
    p.start()
    ret = q.get()
    p.join()

    p2 = Process(target = mc.target_func, args = ('tom', q,))
    p2.start()
    ret = q.get()
    p2.join()

我希望打印出来

Hello bob
1
Hello tom
2

但实际上,打印输出是

Hello bob
1
Hello tom
1    <------------------ Why it's not 2?

我可以知道我错了吗?

非常感谢。

3 个答案:

答案 0 :(得分:2)

在分离的过程中调用

target_funcmc被复制到每个子进程;不在流程之间共享。

使用Thread,你会得到预期的(?)结果。为安全起见,您应该使用锁;我在下面的代码中省略了它。

from threading import Thread
from Queue import Queue

....


if __name__ == '__main__':
    mc = myClass()

    q = Queue()

    p = Thread(target = mc.target_func, args = ('bob', q,))
    p.start()
    ret = q.get()
    p.join()

    p2 = Thread(target = mc.target_func, args = ('tom', q,))
    p2.start()
    ret = q.get()
    p2.join()

答案 1 :(得分:0)

与线程不同,进程不共享内存。第二个进程中的名称__i引用另一个变量,其初始值是在启动子进程时从原始进程复制的。

您可以使用Value或Array数据类型将信息从一个进程传输到另一个进程,或者您可以使用Queue将子进程中的数据推回到原始进程。所有这些类都包含在多处理模块中

http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Queue http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Value http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Array

答案 2 :(得分:0)

变量的值仍然相同,因为您创建的每个进程都获取父进程的内存空间的完整副本,包括您之前创建的mc类实例的副本。因此,当您在每个进程中修改mc的实例变量时,它不会影响主进程中的变量。以下是此行为的更简洁示例:

from multiprocessing import Process 

class A(object):

  def __init__(self):
      self.var = 1
      print "Initialized class: ",self

  def test(self):
      print self
      print "Variable value:",self.var
      self.var += 1

if __name__ == '__main__':

  a = A()

  p1 = Process(target = a.test)
  #Creates a copy of the curent memory space and will print "Variable value: 1"
  p1.start()

  p2 = Process(target = a.test)
  #Will still print "Variable value: 1"
  p2.start()