
子进程可以创建共享内存,但父进程必须等待其就绪后才能安全访问;直接在子进程创建后立即在父进程中尝试连接会导致 filenotfounderror,需通过同步机制(如 event)协调进程间时序。
子进程可以创建共享内存,但父进程必须等待其就绪后才能安全访问;直接在子进程创建后立即在父进程中尝试连接会导致 filenotfounderror,需通过同步机制(如 event)协调进程间时序。
在 Python 的 multiprocessing 模块中,shared_memory.SharedMemory 支持跨进程共享内存,但其生命周期和可见性依赖于操作系统底层的 POSIX 共享内存(Linux/macOS)或等效机制(Windows)。关键限制在于:共享内存对象需在被访问前已由某进程显式创建并完成初始化,且其名称必须全局唯一、可被其他进程发现。
问题中的 Case 3 失败的根本原因并非“子进程不能创建共享内存”,而是典型的竞态条件(race condition):父进程在子进程尚未完成 SharedMemory(name="test", create=True, ...) 调用前,就执行了 SharedMemory(name="test") —— 此时系统中尚无名为 /test 的共享内存段,因此抛出 FileNotFoundError。
✅ 正确做法是引入进程同步原语,确保父进程严格等待子进程完成创建与初始化。推荐使用 multiprocessing.Event,它轻量、跨平台(兼容 Linux/Windows),且语义清晰:
import multiprocessing as mp
import multiprocessing.shared_memory as sm
import numpy as np
def worker(ready_event, done_event):
# 子进程创建共享内存(注意:size 需匹配实际数据需求)
shm = sm.SharedMemory(name="data_buffer", create=True, size=1024)
# 示例:写入 numpy 数据(需确保 buffer 兼容)
arr = np.ndarray((128,), dtype=np.int64, buffer=shm.buf)
arr[:] = np.arange(128) # 写入数据
ready_event.set() # 通知父进程:共享内存已就绪
done_event.wait() # 等待父进程使用完毕
shm.unlink() # 清理资源
if __name__ == '__main__':
# 创建同步事件
ready = mp.Event()
done = mp.Event()
# 启动子进程(建议设为 daemon=True,避免主进程退出时残留)
proc = mp.Process(target=worker, args=(ready, done), daemon=True)
proc.start()
# 父进程等待子进程就绪
ready.wait() # 阻塞直到子进程调用 ready.set()
# 安全连接已存在的共享内存
shm = sm.SharedMemory(name="data_buffer")
# 读取数据(与子进程一致的 shape/dtype)
arr = np.ndarray((128,), dtype=np.int64, buffer=shm.buf)
print("Parent read:", arr[:5]) # 输出: [0 1 2 3 4]
# 通知子进程可清理资源
done.set()
# (可选)主进程显式关闭共享内存(不 unlink,因子进程负责 unlink)
shm.close()
⚠️ 重要注意事项:
- 命名唯一性:共享内存名称在系统范围内必须唯一(Linux 下实际映射为 /name 文件路径),避免硬编码冲突,生产环境建议结合 uuid.uuid4() 生成随机名。
- 资源管理:unlink() 应由最后一个使用者调用(通常为创建者),否则可能导致其他进程访问失效内存;本例中由子进程负责清理,父进程仅调用 close()。
- 数据一致性:共享内存本身不提供原子性保证,若需多进程并发读写同一区域,必须额外加锁(如 mp.Lock)。
- 平台兼容性:shared_memory 在 Python 3.8+ 可用,Windows 支持有限(部分版本需启用 CreateFileMappingW 权限),建议始终包裹在 if __name__ == '__main__': 中以确保正确启动。
对于您的 HDF5 场景:每个子进程可创建独立命名的共享内存段(如 "hdf_chunk_0", "hdf_chunk_1"),写入 NumPy 数组后通知父进程;父进程按序接收、转换为 HDF5 数据集,彻底规避 Queue 或 Manager 带来的序列化/拷贝开销——这正是共享内存优化的核心价值。










