是否可以通过 C++ 扩展强制多个 python 进程共享同一内存?

Is it possible to force multiple python processes to share the same memory via a C++ extension?

这是我的尝试:

int* globalvar = new int[8];
void cpp_init(){
    for (int i = 0; i < 8; i++)
        globalvar[i] = 0;
}
void writeAtIndex(int index, int value){
    globalvar[index] = value;
}
int accessIndex(int index){
    return globalvar[index];
}
BOOST_PYTHON_MODULE(MpUtils){
    def("cpp_init", &cpp_init);
    def("writeAtIndex", &writeAtIndex);
    def("accessIndex", &accessIndex);
}

并在 python 文件中

def do_stuff(index):
    writeAtIndex(index, randint(1, 100))
    time.sleep(index/10)
    print([accessIndex(i) for i in range(8)])

if __name__ == '__main__':
    freeze_support()
    processes = []
    cpp_init()
    for i in range(0, 10):
        processes.append( Process( target=do_stuff, args=(i,) ) )
    for process in processes:
        process.start()
    for process in processes:
        process.join()

输出是这样的:

[48, 0, 0, 0, 0, 0, 0, 0]
[0, 23, 0, 0, 0, 0, 0, 0]
[0, 0, 88, 0, 0, 0, 0, 0]
[0, 0, 0, 9, 0, 0, 0, 0]
[0, 0, 0, 0, 18, 0, 0, 0]
[0, 0, 0, 0, 0, 59, 0, 0]
[0, 0, 0, 0, 0, 0, 12, 0]
[0, 0, 0, 0, 0, 0, 0, 26]

有人可以解释为什么这不起作用吗?我尝试打印 globalvar,它始终是相同的值。不应该有任何竞争条件,因为等待 0.1 到 0.8 秒应该足以让计算机写一些东西。 C++ 不应该直接访问指针的位置吗?

谢谢

下面的循环将创建一个进程列表,其中第一个 args,从 09 是连续的。 (第一个过程有 0,第二个过程有 1 等等。)

    for i in range(0, 10):
        processes.append( Process( target=do_stuff, args=(i,) ) )

写入可能需要一个数字列表,但对 writeAtIndex 的调用将仅使用第一个元素来调用:

def do_stuff(index):
    writeAtIndex(index, randint(1, 100))

函数 writeAtIndex 需要一个 int,而不是列表:

void writeAtIndex(int index, int value)

这就是为什么您的输出在每个位置都有一个值。

正如@Voo 和 docs 所说:

The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads.

Process objects represent activity that is run in a separate process.

所以每个进程都有一个globalvar

如果你想在线程之间共享数据,你可以使用 threading 模块。不过,您应该阅读一些详细信息:

due to the Global Interpreter Lock, only one thread can execute Python code at once (even though certain performance-oriented libraries might overcome this limitation). If you want your application to make better use of the computational resources of multi-core machines, you are advised to use multiprocessing or concurrent.futures.ProcessPoolExecutor.

进程通常只能访问它们自己的内存space。 您可以使用 multiprocessing 的 shared_memory 模块跨进程共享同一个数组。请参阅链接页面中的示例。