我可以定义共享内存缓冲区,将其传递给子进程并在API调用中使用它吗?

时间:2017-05-03 10:59:04

标签: python ctypes python-multiprocessing

我想在Python中将内存缓冲区定义为数组,这些数组作为指针数组传递给C函数。 C函数在返回之前用缓冲区填充数据。 C API是用于访问我使用ctypes包装的ETTUS B210软件定义无线电的DLL。我简化了下面的代码,只是为了展示我想要做的事情的基本要素。

我在单个线程中工作但如果缓冲区在主线程中定义且API调用在一个单独的进程中,则无法实现相同的功能。乍一看multiprocessing.RawArray是我需要的,但我找不到一种方法来访问底层数据存储器作为一个指针,我可以在调用C函数时传输。

我需要使用多个进程,部分原因是因为硬件的C API(不是我写的)一次只处理一个硬件设备,但可以运行多个实例。

我以这种方式处理缓冲区的原因主要是速度 - 数组可能非常大> 2000000浮点数并且一遍又一遍地使用,所以我想分配一次并重用。将数据通过管道从一个过程传递到另一个过程是一个巨大的瓶颈 - 虽然它确实有点工作。

作为一个单独的线程我做这样的事情:

    def stream(n_samples, buffer1, buffer2):
        buffer_list = (c_void_p*2)()
        buffer_list[0] = cast( pointer( buffer1 ), c_void_p ) 
        buffer_list[1] = cast( pointer( buffer2 ), c_void_p ) 
        windll.myapi.stream(c_int(n_samples), byref(buffer_list))

    if __name__ == '__main__':

        buf1 = ( c_float * ( 2*n_samples))()
        buf2 = ( c_float * ( 2*n_samples))()
        stream(n_samples, buf1, buf2)

如果stream()现在已成为流程的一部分,我尝试了这一点,但它没有按照我的意愿行事:

        buf1 = RawArray('f', 2*n_samples) 
        buf2 = RawArray('f', 2*n_samples) 
        p1 = process(target=stream, args=(n_samples, buf1, buf2,))
        p1.start()
        p1.join()

尽管API似乎在某处填充了内存(并且没有抛出异常,这是我在指针定义错误时通常会发生的情况),但是无法通过buf1, buf2对象访问它。

作为附录:我使用了几个缓冲区,在单线程版本中我定义了一个大缓冲区,然后计算传递给API的偏移指针。在多处理版本中执行此操作会很有用,但不是必需的。

0 个答案:

没有答案