我是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?
我可以知道我错了吗?
非常感谢。
答案 0 :(得分:2)
target_func
。 mc
被复制到每个子进程;不在流程之间共享。
使用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()