我正在运行两个Python 3解释器,一个在Linux上,另一个在Windows系统上。他们使用multiprocessing.connection
(Client
和Listener
)进行通信(即交换数据)。在这两者之间,我必须保持ctypes
指针所代表的任意数据结构的内容同步。
问题是我需要有效地来回传送数据的内容。 multiprocessing.connection
将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'>
答案 0 :(得分:1)
假设每个数据部分都不是那么大(因为解决方案需要复制),可以这样做(在交互式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]