我的Python应用程序使用multiprocessing.RawArray
创建进程之间共享的数组。现在,为了加快计算速度,我想在C ++函数中修改此数组。将指向基础内存的指针传递到接受void *
参数的C ++函数的安全方法是什么?
该功能在pxd
文件中定义为:
cdef extern from 'lib/lib.hpp':
void fun(void *buffer)
到目前为止,我的幼稚尝试:
buffer = multiprocessing.RawArray(ctypes.c_ubyte, 10000)
clib.fun(ctypes.cast(self.queue_obj_buffer, ctypes.c_void_p))
这会使Cython编译失败,并出现以下错误:Cannot convert Python object to 'void *'
我也尝试了ctypes.addressof
,但结果相似。
我确实知道,我将需要一种方法来从每个参与的进程中分别查询此指针,因为该相同的内存区域将在进程地址空间中进行不同的映射。但这不是问题,到目前为止,我只是在努力获取所有指针。我应该完全使用其他方法并从C ++中分配共享内存,还是可以做我正在做的事情?
[RawArray
应该有一个buffer protocal,然后很容易获得基础指针,因为Cython通过memory view对它有很好的支持,所以下面的代码应该起作用:
%%cython
import ctypes
from multiprocessing.sharedctypes import RawArray
ctypedef unsigned char ubyte
cdef void func(void* buffer, int size):
cdef ubyte *buf = <ubyte*>buffer
cdef int i
for i in range(size):
buf[i] += 1
def test():
cdef ubyte[::1] view = RawArray(ctypes.c_ubyte, [1,2,3,4,5])
func(<void*>&view[0], len(view))
print(list(view))
test() # [2, 3, 4, 5, 6]
根据您的描述,您应该了解Cython对shared memory parallelism的支持>
multiprocessing.RawArray
是ctypes.Array
,因此可以通过ctypes.Array
获得基础缓冲区的地址。该地址可以重新解释为ctypes.addressof
。这是一个例子: