shared_memory创建后进程读不到数据,因它仅提供裸内存,无同步机制和元信息;读进程需明确数据起始、长度及格式,常见错误是未显式写入或读取整块未初始化内存。

shared_memory 创建后为什么进程读不到数据?
因为 shared_memory.SharedMemory 只分配一块裸内存,不带任何同步机制或数据结构元信息。写进程把字节写进去,读进程得知道“从哪开始、写了多少、按什么格式解释”。常见错误是写入后没调用 shm.buf[:n] = data 实际拷贝,或读时直接 bytes(shm.buf) 读了整块未初始化内存。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 写进程必须显式拷贝:用
shm.buf[:len(data)] = data(data是bytes)或np.ndarray的copyto; - 读进程不能假设长度——需额外通过文件、信号量或固定偏移约定数据边界;
- 避免用
shm.name直接传参跨进程:Windows 下名字不可见,Linux 下需确保权限一致,推荐用os.path.join('/dev/shm', name)检查是否存在。
怎么安全地在多个进程间传递 NumPy 数组?
NumPy 的 frombuffer 和 shared_memory 配合最常用,但关键点在于数组形状、dtype、字节序必须完全一致,且缓冲区大小要精确匹配 shape × itemsize。否则会静默读错数据,甚至 segfault。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 创建时用
np.ndarray(shape, dtype=dtype, buffer=shm.buf),别用np.frombuffer(shm.buf, dtype)——后者默认展平且不检查长度; - 务必在创建共享内存前计算好所需字节数:
size = int(np.prod(shape) * np.dtype(dtype).itemsize); - 写进程写完应设一个标志位(如
shm.buf[0] = 1),读进程轮询该字节,避免读到中间状态; - 不要复用
shm.buf给多个不同 shape 的数组——底层内存没重置,旧数据残留会导致越界访问。
为什么 fork 后子进程能直接访问 shared\_memory,但 spawn 就不行?
Linux/macOS 的 fork 会复制页表,子进程继承父进程的 shm 对象句柄和映射地址;而 spawn(Windows 默认 / Python 3.8+ macOS/Linux 可选)是全新进程,没有继承,必须重新 attach 同名共享内存块。错误现象是 FileNotFoundError: No such file or directory 或 PermissionError。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 统一用
multiprocessing.get_context('spawn')启动,并在子进程中用SharedMemory(name=shm_name)重新连接; - 名字必须全局唯一且不含路径分隔符(如
shm_123合法,shm/123在 Linux 下会失败); - Linux 下可查
/dev/shm/确认是否创建成功:ls -l /dev/shm/ | grep your_name; - spawn 场景下,务必捕获
FileNotFoundError并加重试逻辑,因为主进程可能还没完成create=True步骤。
shared\_memory 用完不 close/unlink 会怎样?
不调 shm.close() 不影响当前进程释放映射,但不调 shm.unlink() 会导致内存泄漏:Linux 下 /dev/shm/xxx 文件残留,直到系统重启;macOS 下对应 shm_open 的内核对象不释放;Windows 下表现为句柄泄漏。多次运行脚本后可能报 OSError: [Errno 24] Too many open files。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 必须用
try/finally或with语句确保unlink()执行(注意:只有创建者才能 unlink); - 多进程场景下,约定由主进程负责
unlink,子进程只close; - 调试时可用
ipcs -m(Linux)或ls /dev/shm快速确认残留; - 不要依赖
__del__自动清理——GC 时间不确定,且异常退出时可能跳过。
真正麻烦的是跨进程同步时机:比如一个进程崩溃没来得及写完成标记,另一个进程永远卡在轮询。这种边界情况没法靠 shared_memory 本身解决,得配信号量或超时重试。


















