代码之家  ›  专栏  ›  技术社区  ›  atline

为什么在两个不同的多处理过程中对象是相同的?

  •  1
  • atline  · 技术社区  · 3 年前

    我有下一个代码:

    test.py:

    import multiprocessing
    import time
    
    class A:
        def __action(self):
            print("another process:")
            print(id(self))
    
        def run(self):
            print("this process")
            print(id(self))
            p = multiprocessing.Process(target=self.__action, daemon=True)
            p.start()
    
    a = A()
    print("main")
    print(id(a))
    a.run()
    time.sleep(3)
    

    它运行如下:

    $ python3 test.py
    main
    140643898766000
    this process
    140643898766000
    another process:
    140643898766000
    

    但从 doc 下一个:

    如上所述,在进行并发编程时,通常最好尽可能避免使用共享状态。当使用多个进程时尤其如此。

    但是,如果确实需要使用一些共享数据,那么多处理提供了几种方法。

    共享内存

    数据可以使用Value或Array存储在共享内存映射中。

    所以它看起来只有显式定义 Value / Array 两个进程是否可以具有相同的对象。那么,为什么 A object 在两个不同的进程中现在有相同的id?

    1 回复  |  直到 3 年前
        1
  •  4
  •   Tim Peters    3 年前

    您显然是在一些类似Linux的操作系统下运行的,其中多处理使用 fork() 以创建工作进程。在下面 分叉() ,新进程将获得父进程地址空间的写时复制克隆。因此,是的,在 分叉() 会有相同的 id() ,但它们仍然是完全不同的对象。地址是虚拟的。这个 self 在主要的生活过程中 身体的 内存比 自己 在工人过程中。它们在每个进程中都有相同的虚拟地址,这只是操作系统如何实现的结果 分叉() 。在一个进程中对对象所做的更改在另一个进程中将看不到。

    在没有 分叉() (主要是Windows),或者如果你告诉多处理使用“spawn”而不是“fork”,那么这是非常不可能的(尽管仍然可能) 自己 将保留相同的虚拟地址。