SharedMemory读写慢的根本原因是Python对象序列化开销,高效做法是仅共享原始内存视图(如numpy.ndarray或memoryview),避免pickle;初始化需严格匹配shape与dtype,子进程须用相同name重新attach;多进程写需手动加锁,SharedMemory本身无同步机制。

SharedMemory 创建后为什么读写还是慢?
根本原因不是 SharedMemory 本身慢,而是你没绕过 Python 对象序列化这层开销。直接往 SharedMemory 里塞 dict 或 list,本质是把数据先 pickle 再拷贝——这和用 Queue 没本质区别。
真正高效的做法:只共享原始内存视图(numpy.ndarray 或 memoryview),所有进程直接读写同一块裸内存。
- 创建时指定
size要精确,宁大勿小;多进程同时写同一偏移需自行加锁(multiprocessing.Lock) - 避免反复调用
.buf或memoryview(...),复用已有视图对象 - 若数据结构复杂(如嵌套字段),用
struct.pack手动布局,别依赖dataclass+asdict
numpy.ndarray + SharedMemory 组合怎么初始化才不报错?
常见错误是形状/类型不匹配导致 ValueError: buffer size mismatch,或子进程访问时触发 BufferError: memoryview is not contiguous。
- 主进程创建
SharedMemory后,必须用np.ndarray(shape=..., dtype=..., buffer=shm.buf)构造视图,不能用np.frombuffer(shm.buf, ...)(后者可能产生非写入安全的副本) - dtype 必须显式指定(如
np.float32),不能依赖默认;shape 要与总字节数严格一致:shm.size == np.prod(shape) * dtype.itemsize - 子进程中需用相同
name重新 attach:shm = SharedMemory(name="xxx"),再套同样ndarray构造逻辑
多个进程频繁读写同一 SharedMemory 区域会卡死吗?
不会自动卡死,但会出现数据错乱或脏读——SharedMemory 本身不提供同步机制,它只是裸内存。
- 纯读场景(一个写、多个读)可完全无锁,性能接近本地数组访问
- 有写操作时,必须额外配
multiprocessing.Semaphore或Lock,且锁粒度要细:比如按数组行/块加锁,而非整个shm - 避免在锁内做耗时操作(如 IO、复杂计算),否则其他进程会长时间阻塞
- 注意 Windows 下
SharedMemory名称区分大小写,Linux 不区分;跨平台部署时统一用小写 name
SharedMemory 和 multiprocessing.Array 哪个更快?
实测 SharedMemory + ndarray 稳定快 2–5 倍,尤其在 >1MB 数据量时。但 Array 更简单、自带同步语义(内部用锁保护),适合小规模、结构固定的数据。
-
Array底层其实也用了共享内存,但封装了锁和类型检查,每次读写都触发 Python 层代理逻辑 -
SharedMemory是“零拷贝”前提:你得自己保证数据布局连续、类型对齐、并发安全 - 如果只需要共享几个标量(如计数器、标志位),用
Value('i', 0)更轻量,比开SharedMemory省资源
真正难的是边界对齐和生命周期管理:shm.close() 只释放本进程句柄,shm.unlink() 必须由创建者调用且只能调一次,否则其他进程再 attach 会失败。这个点容易漏,一跑久就占满系统共享内存段。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











