我是 Pythonmultiprocessing
的新手,根本无法理解这段代码是如何工作的:
from multiprocessing import Process, Queue
class C:
dic = {}
def put_in_queue(q, v):
c = C()
print("before update:", c.dic)
c.dic.update({0: v})
print("after update", c.dic)
q.put(c)
def main():
queue = Queue()
put_in_queue(queue, 0)
c = queue.get()
print("get from queue dic:", c.dic)
p = Process(target=put_in_queue, args=(queue, 1))
p.start()
p.join()
c = queue.get()
print("get from queue modified by process dic:", c.dic)
if __name__ == '__main__':
main()
其输出如下:
before update: {}
after update {0: 0}
get from queue dic: {0: 0}
before update: {0: 0}
after update {0: 1}
get from queue modified by process dic: {0: 0}
基本上有两个主要问题我似乎无法回答:
为什么进程对字典所做的更新没有传播回主进程,即使修改的对象应该通过队列传递。
为什么过程中新创建的对象似乎已经具有字典的更改值,即使它是新创建的并且尚未对其进行更新?
我的猜测是它与传递自定义对象而不是一些简单类型有关。
也许这是一个非常愚蠢的问题,但我还不明白。一些解释或帮助将不胜感激。
我认为你的子问题源于对类在 Python 中如何工作的误解。您定义类C
的方式:
class C:
dic = {}
意味着所有类实例将共享相同的dic
属性,因为当这样声明时,它是一个class
而不是实例属性。
要将其更改为实例属性,您需要执行以下操作:
class C:
def __init__(self):
self.dic = {}
这为每个实例提供了自己的独立属性(该属性不会受到通过其他实例对其所做的更改的影响,这是以另一种方式完成时发生的情况(。
通过此更改,脚本的输出将变为:
before update: {}
after update {0: 0}
get from queue dic: {0: 0}
before update: {}
after update {0: 1}
get from queue modified by process dic: {0: 1}