在多个平台上跨 python 个进程同步由 ctypes 指针表示的内存

Syncronizing memory represented by ctypes pointers accross python processes on multiple platforms

我是 运行 两名 Python 3 名口译员,一名在 Linux 上,一名在 Windows 系统上。他们使用 multiprocessing.connectionClientListener)进行通信(即交换数据)。在两者之间,我必须保持由 ctypes 指针表示的任意数据结构的内容同步。

问题是我需要高效地来回传送数据内容。 multiprocessing.connectionpickle 传送任何数据,因此我必须将数据序列化为可以 pickle 的内容。

到目前为止,我将内存中的每个字节序列都变成了一个 Python 列表 Python 整数。嗯,它(至少)有效......

def generate_pointer_from_int_list(int_array):

    return ctypes.pointer((ctypes.c_ubyte * len(int_array))(*int_array))


def overwrite_pointer_with_int_list(ctypes_pointer, int_array):

    (ctypes.c_ubyte * len(int_array)).from_address(ctypes.c_void_p.from_buffer(ctypes_pointer).value)[:] = int_array[:]


def serialize_pointer_into_int_list(ctypes_pointer, size_bytes):

    return (ctypes.c_ubyte * size_bytes).from_address(ctypes.c_void_p.from_buffer(ctypes_pointer).value)[:]

我想知道是否有办法提高效率(就需要传输的数据量和速度而言,当然)。

我的一个想法是使用 Python 字节的字符串而不是整数列表,这将减少所需的内存量。但是,我没能成功。我该如何更改上述例程?

我还有哪些可能更好/更快/内存效率更高的选项?


serialize_pointer_into_int_list 的用法示例:

sample_len = 5
sample_p = ctypes.pointer((ctypes.c_double * sample_len)(1.0, 2.0, 3.0, 4.0, 5.0))
sample_int_list = serialize_pointer_into_int_list(sample_p, sample_len * ctypes.sizeof(ctypes.c_double))
print(sample_int_list)
print(type(sample_int_list))

输出:

[0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 8, 64, 0, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 0, 0, 0, 20, 64]
<class 'list'>

假设每个数据部分都没有那么大(因为解决方案需要复制),可以通过这种方式完成(在交互式 shell 中显示):

>>> import pickle
>>> import ctypes
>>> b = (ctypes.c_double * 5)(1.0, 2.0, 3.0, 4.0, 5.0)  # Arbitrary data
>>> d = pickle.dumps(bytes(b))
>>> c = pickle.loads(d)
>>> a = (ctypes.c_double * 5).from_buffer_copy(c)
>>> a
<__main__.c_double_Array_5 object at 0x02F6C9E0>
>>> list(a)
[1.0, 2.0, 3.0, 4.0, 5.0]