Python: 在另一个进程中通过id获取对象

Python: Get object by id in another process

问题

我正在制作多处理块生成器,但我无法通过子进程的 ID 获取对象。我在 Windows 10.

代码

import _ctypes
import classes as pycraft
import multiprocessing

def start_generaion(window):
    # We don't have to worry about infinite loops, because
    # this is going to be run in another thread, using popen.
    try:
        world = _ctypes.PyObj_FromPtr(window).model
        print(world, flush=True)
        
        while True:
            for i in world._queue:
                world.all_chunks[i].generate()
    except Exception as e:
        print(f'Error in world generation process. \n{e}', flush=True)

if __name__ == '__main__':
    world = pycraft.world()
    world = id(world)

    world_gen_process = multiprocessing.Process(target = start_generaion, args = (world,))
    world_gen_process.start()

提前致谢!

以下代码将常规对象的 ID 传递给另一个进程,它能够从 Linux 下的 ID 成功恢复对象:

import _ctypes
import multiprocessing
import sys

def foo(id1, label):
    try:
        print(label, id1)
        v = _ctypes.PyObj_FromPtr(id1)
        print(v)
    except:
        print("Unexpected error:", sys.exc_info()[0])
    finally:
        print('finally')

if __name__ == '__main__':
    d = {'a': 1}
    id1 = id(d)
    foo(id1, 'Main process id:')
    p = multiprocessing.Process(target=foo, args=(id1, 'Subprocess id:'))
    p.start()
    p.join()

打印:

Main process id: 140443371291200
{'a': 1}
finally
Subprocess id: 140443371291200
{'a': 1}
finally

但是在Windows下运行时,输出的都是:

Main process id: 1687385043136
{'a': 1}
finally
Subprocess id: 1687385043136

子进程在没有执行我无法解释的 exceptfinally 块的情况下突然终止。

问题在于,当使用 spawn 方法创建新进程时,就像 Windows 的情况一样,该进程不会从主进程继承任何内容。相反,会创建一个新地址 space,并在该 space 中启动一个 Python 解释器,并重新读取源文件,在全局范围内执行所有内容,作为初始化内存的方式,为调用工作函数(在我的示例中为 foo)。但是变量,在新地址中不会有相同的地址 space 除非是最大的巧合。

您没有说明您 运行 正在使用哪个平台,但我强烈怀疑它使用 spawn 来创建新进程。 但即使在 Linux 下,虽然您能够重新创建对象引用,但它实际上只是原始对象的副本(技术上涉及写时复制语义,但一旦引用计数为对象增加,这将导致制作实际副本)。