PyTorch share_memory_()与Python内置shared_memory对比:为何无需显式访问共享内存块?
PyTorch multiprocessing 共享Tensor无需显式访问共享内存的原理
核心差异根源
PyTorch的share_memory_()与Python内置shared_memory的行为差异,本质在于进程间传递对象时的序列化/反序列化逻辑,以及共享内存的关联方式。
1. PyTorch Tensor的共享内存与序列化实现
当你调用Tensor.share_memory_()时:
- 该方法会将Tensor的底层数据存储从进程私有内存,迁移到跨进程共享内存区域(Windows下使用命名共享内存,Unix-like系统使用mmap)。
- 同时会标记该Tensor为"可跨进程共享",PyTorch的multiprocessing模块会使用自定义的序列化逻辑(替代默认pickle)来处理这类Tensor:
- 父进程传递Tensor给子进程时,序列化的内容包含共享内存的标识信息(比如Windows下的共享内存名称),而非Tensor的数据本身。
- 子进程反序列化时,会自动根据这些标识信息,直接关联到已存在的共享内存块,生成的Tensor对象直接指向共享内存地址。
这就解释了你的PyTorch示例中,子进程的foo函数不需要额外操作,直接访问Tensor就能读到父进程更新后的值——因为这个Tensor对象从一开始就和共享内存绑定了。
2. Python内置shared_memory的工作逻辑
内置shared_memory的设计更底层:
- 你需要手动创建共享内存块,再将numpy数组关联到这块内存。
- 父进程传递给子进程的只是共享内存的名称、数组形状、数据类型这些元信息,而非关联好的数组对象。
- 子进程必须显式调用
shared_memory.SharedMemory(name=...)打开共享内存,再创建numpy数组关联到内存缓冲区,才能访问到共享内存中的最新数据。如果跳过这一步,子进程根本没有能指向共享内存的对象,自然看不到父进程的更新。
3. Windows平台的特殊影响(你的运行环境)
Windows系统不支持fork创建进程,只能用spawn模式:所有传递给子进程的对象都必须被完整序列化/反序列化。
- PyTorch针对spawn模式做了优化,Tensor的序列化逻辑自动处理了共享内存的关联,无需用户手动干预。
- 而内置
shared_memory在spawn模式下,只能传递元信息,必须由用户手动完成共享内存的重新关联操作。
对比验证
- 在你的PyTorch示例中,子进程拿到的
a是一个已经绑定共享内存的Tensor实例,print(a)时直接读取共享内存的实时数据。 - 在你的内置
shared_memory示例中,如果去掉existing_shm = shared_memory.SharedMemory(name=shm_name)和a = np.ndarray(...)这两步,子进程根本无法访问到共享内存中的更新值。
内容的提问来源于stack exchange,提问作者abc
相关产品推荐
相关产品推荐

