Python 多处理进程、队列和对象

Python 多处理进程、队列和对象,python,object,process,multiprocessing,queue,Python,Object,Process,Multiprocessing,Queue,我不熟悉Python多处理,根本无法理解这段代码是如何工作的: 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 m

我不熟悉Python
多处理
,根本无法理解这段代码是如何工作的:

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}
有两个主要问题我似乎无法回答:

  • 为什么即使修改的对象应该通过队列传递,进程对字典的更新也不会传播回主进程

  • 为什么过程中新创建的对象似乎已经具有dict的更改值,即使它是新创建的并且尚未对其进行更新

  • 我的猜测是,它与传递一个自定义对象而不是一些简单类型有关


    也许这是一个相当愚蠢的问题,但我还不明白。如果您能提供一些解释或帮助,我们将不胜感激。

    我认为您的子问题源于对类在Python中如何工作的误解。您定义class
    C
    的方式:

    class C:
        dic = {}
    
    这意味着所有类实例都将共享相同的
    dic
    属性,因为这样声明时,它是
    ,而不是实例属性

    要将其更改为实例属性,您需要执行以下操作:

    class C:
        def __init__(self):
            self.dic = {}
    
    这为每个实例提供了自己的独立属性(不会受到通过其他实例对其进行的更改的影响,这是以其他方式进行更改时所发生的情况)

    更改后,脚本的输出将变为:

    更新之前的
    :{}
    更新后{0:0}
    从队列dic获取:{0:0}
    更新前:{}
    更新后{0:1}
    从进程dic修改的队列获取:{0:1}
    
    非常感谢!真不敢相信我竟然犯了这么简单的错误!再次感谢:)