能否使用自定义数据类型在共享内存中创建NumPy数组?
能否使用自定义数据类型在共享内存中创建NumPy数组?
嘿,这个问题我之前也踩过类似的坑!答案是完全可以,但你当前的写法有个关键错误,导致抛出了那个TypeError。
问题出在哪?
你用了np.array()函数并传入buffer参数,但实际上**np.array()根本不支持buffer这个关键字参数**——你大概率是把它和np.ndarray()的构造函数搞混了!np.array()的核心作用是从列表、元组这类已有数据集合生成数组,而要直接把共享内存缓冲区包装成NumPy数组,不管是简单dtype还是你这种自定义的结构化dtype,都得用np.ndarray来实现。
另外,你同时给np.array()传入了数据列表和buffer参数,这本身就逻辑冲突:np.array()会优先处理你传入的列表数据,完全不会理会buffer参数,这也是报错的直接原因。
正确的实现方法
我们换用np.ndarray()来包装共享内存缓冲区,步骤很清晰:
- 先定义你的自定义结构化dtype,计算出单个元素的字节数,再根据需要的元素个数算出共享内存的总大小(避免内存不够用)
- 创建共享内存对象
- 用
np.ndarray()把共享内存缓冲区包装成数组,指定好shape、dtype和buffer - 最后给数组赋值即可
来看具体的代码示例:
import numpy as np from multiprocessing import shared_memory # 定义自定义结构化数据类型 my_dtype = np.dtype([('name', 'U10'), ('age', 'i4'), ('weight', 'f4')]) # 计算需要的共享内存大小:元素个数 × 单个元素字节数 element_count = 2 total_size = element_count * my_dtype.itemsize # 创建共享内存对象 b_shared_memory = shared_memory.SharedMemory(create=True, name="test235", size=total_size) # 用np.ndarray包装共享内存缓冲区,生成结构化数组 x = np.ndarray(shape=(element_count,), dtype=my_dtype, buffer=b_shared_memory.buf) # 给数组赋值 x[:] = [('Rex', 9, 81.0), ('Fido', 3, 27.0)] # 验证结果 print(x)
额外注意事项
- 一定要准确计算共享内存大小:如果分配的内存比实际需要的小,会导致内存越界,出现莫名其妙的错误;如果太大则会浪费内存,用
dtype.itemsize能精准获取单个元素的字节数。 - 使用完共享内存后记得清理:在创建共享内存的进程里,用完要先调用
b_shared_memory.close(),再调用b_shared_memory.unlink()释放内存;其他访问该共享内存的进程只需要调用close()即可。 - 跨进程访问时,只需要在另一个进程中打开已有的共享内存(用
shared_memory.SharedMemory(name="test235")),再用np.ndarray()包装成数组就能直接读写数据了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

