是否可以通过 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
,从 0
到 9
是连续的。 (第一个过程有 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 模块跨进程共享同一个数组。请参阅链接页面中的示例。
这是我的尝试:
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
,从 0
到 9
是连续的。 (第一个过程有 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 模块跨进程共享同一个数组。请参阅链接页面中的示例。