Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多个平台上跨python进程同步由ctypes指针表示的内存_Python_Python 3.x_Serialization_Ctypes_Python Multiprocessing - Fatal编程技术网

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

在多个平台上跨python进程同步由ctypes指针表示的内存,python,python-3.x,serialization,ctypes,python-multiprocessing,Python,Python 3.x,Serialization,Ctypes,Python Multiprocessing,我正在运行两个Python3解释器,一个在Linux上,一个在Windows系统上。它们使用多处理连接客户端和侦听器进行通信,即交换数据。在这两者之间,我必须保持由ctypes指针表示的任意数据结构的内容同步 问题是我需要高效地来回传送数据的内容。multiprocessing.connection将对发送的任何数据进行pickle,因此我必须将数据序列化为可以进行pickle的内容 到目前为止,我将内存中的每个字节序列转换为Python整数的Python列表。好吧,它至少起作用了 def ge

我正在运行两个Python3解释器,一个在Linux上,一个在Windows系统上。它们使用多处理连接客户端和侦听器进行通信,即交换数据。在这两者之间,我必须保持由ctypes指针表示的任意数据结构的内容同步

问题是我需要高效地来回传送数据的内容。multiprocessing.connection将对发送的任何数据进行pickle,因此我必须将数据序列化为可以进行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字节字符串而不是整数列表,这将减少所需的内存量。然而,我没有设法使它工作。我怎样才能改变上述程序呢

我还有哪些更好/更快/更节省内存的选项

将\u指针\u序列化到\u int\u列表的用法示例:

输出:

[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'>

假设每个数据部分都没有那么大,因为复制对于解决方案来说是必要的,那么可以按照interactive 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]

将指针序列化到int列表会返回一个不可拾取的ctypes数组。@MichaelButscher可能是c&p问题?它对我有用。我在问题中添加了一个示例,演示了如何正确使用serialize_pointer_to_int_list。我监督了最后的[:]将ctypes数组转换为列表。在b上运行字节是一个非常酷的主意,谢谢。我不知道这在ctypes对象上是可能的。但我不明白的是,如果内存段的长度与已知类型的固定长度数组的示例中的长度不明显,如何考虑内存段的长度。我的serialize_指针例程故意有一个size_bytes参数。为此,bytes例程没有这样的参数。毕竟,我希望它只接受任何类型的指针,而不管它指向的数据类型是什么。@s-m-e字节对象中的字节数可以用通常的lenc检索。
>>> 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]