change object value in threads using python

会有一股神秘感。 提交于 2020-03-23 12:00:53

问题


I am very new to Python, thus am possibly asking a simple question.

I am wrting a multiprocess code with 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()

I expect the print out should be

Hello bob
1
Hello tom
2

But actually, the print out is

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

May I know what am I wrong?

Many thanks.


回答1:


target_func is called in separated process. mc is copied to each subprocess; not shared between processes.

Using Thread, you will get expected(?) result. For safety you should use lock; I omitted it in following code.

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()



回答2:


Processes don't share memory, unlike threads. The name __i in the second process refers to a different variable, whose initial value was copied from the original process when you launched the subprocess.

You can use the Value or Array data types to transfer information from one process to another, or you can use the Queue to push data from the subprocess back the the original. All of these classes are included in the multiprocessing module

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




回答3:


The value of the variable is still the same since each process you create gets a full copy of the memory space of the parent process, including a copy of the mc class instance that you created earlier. Hence, when you modify the instance variable of mc from within each process, it does not affect the variable in your main process. Here's a more concise example of this behavior:

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()


来源:https://stackoverflow.com/questions/18226326/change-object-value-in-threads-using-python

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