Python 使用现有缓冲区创建 SharedMemory 实例(来自 marshal.dumps() 的字节)

Python create SharedMemory instance using existing buffer (bytes from marshal.dumps())

我想创建一个 multiprocessing.shared_memory.SharedMemory 从缓冲区外部传递的实例,用于保存数据。

我的用例如下:

import marshal

from multiprocessing.shared_memory import SharedMemory


data = {'foo' 1, 'bar': 'some text'}
data_bytes = marshal.dumps(data)
shm = SharedMemory(create=True, size=len(data_bytes))

for i,b in enumerate(data_bytes):
    shm.buf[i] = b

如您所见,我需要序列化一些数据(以便稍后在多个进程之间共享)。上面的代码片段使用的内存是实际需要的两倍,因为存储在 data_bytes 字节变量中的序列化数据需要复制到 SharedMemory 缓冲区中(这也需要相当多的内存,因为在我的用例中 data 是 1 GB)。

到目前为止我发现的唯一不可行的解决方案是猜测 space 序列化数据将占用多少,在 SharedMemory 实例中分配足够的 space 并具有 marshal 写在上面,例如

shm = SharedMemory(create=True, size=BIG_ENOUGHT_SIZE)
marshal.dump(data, shm.buf.obj)

但是,如果我的猜测太低,marshal.dump(data, shm.buf.obj)(正确)会抛出错误,因为 space 不足以写入序列化数据。

目前似乎不可能将缓冲区对象传递给 SharedMemory 实例 (Python 3.9)。 我取得的最好成绩是使用切片赋值来复制数据(如果您使用的是 CPython,这比使用 for 循环要快得多)。

import marshal

from multiprocessing.shared_memory import SharedMemory


data = {'foo' 1, 'bar': 'some text'}
data_bytes = marshal.dumps(data)
data_bytes_len = len(data_bytes)

shm = SharedMemory(create=True, size=data_bytes_len)

# 'shm' may allocate more memory than the actual requested amount
# hence we must specify the length of data_bytes in the slice assignment
shm.buf[:data_bytes_len] = data_bytes