Python跨多个独立程序实现只读共享内存持久访问的报错问题咨询
问题根源
你遇到的问题是Python标准库multiprocessing模块自带的资源追踪器(resource_tracker)的默认行为导致的:
- 每个使用
multiprocessing.shared_memory的进程,都会自动将打开的共享内存段注册到资源追踪器 - 当client进程退出时,资源追踪器会认为所有该进程打开的共享内存段都属于"泄漏资源",会自动执行
unlink操作销毁共享内存,哪怕你只调用了close()没有主动调用unlink() - 这就是第一次运行client后共享内存消失、第二次运行找不到文件的原因,对应的警告也是资源追踪器准备自动销毁共享内存时触发的。
解决方案
对现有代码改动最小的方案是:在client端打开共享内存后,主动将共享内存段从资源追踪器的监控列表中移除,让资源追踪器不要管这部分共享内存的生命周期,交给server进程统一管理。
修改后的完整client代码
import numpy as np from multiprocessing import shared_memory, resource_tracker class DataProvider: def __init__(self, shared_memory_name): self._existing_shm_1 = shared_memory.SharedMemory(name=f"{shared_memory_name}_uint_np") self._existing_shm_2 = shared_memory.SharedMemory(name=f"{shared_memory_name}_float_np") # 新增:将当前打开的共享内存从资源追踪器中注销,避免退出时被自动销毁 resource_tracker.unregister(self._existing_shm_1._name, "shared_memory") resource_tracker.unregister(self._existing_shm_2._name, "shared_memory") self._uint_np = np.ndarray((64, 4, 28, 28), dtype=np.uint8, buffer=self._existing_shm_1.buf) self._float_np = np.ndarray((64, 8), dtype=np.float32, buffer=self._existing_shm_2.buf) def get_item(self, idx): uint_np = self._uint_np[idx] float_np = self._float_np[idx] return uint_np, float_np def __del__(self): if self._existing_shm_1 is not None and self._existing_shm_2 is not None: self._existing_shm_1.close() self._existing_shm_2.close() if __name__ == "__main__": data_provider = DataProvider(shared_memory_name="test") uint_np, float_np = data_provider.get_item(0) # 打印访问数据的信息 print(uint_np.std(), float_np.std())
注意事项
- 共享内存的生命周期完全由server进程管理:只要server进程不退出,共享内存就会一直存在,支持任意多个client进程多次访问
- 只有确认所有client都不再使用共享内存后,再退出server进程,此时server的
__del__方法会执行unlink操作,真正释放共享内存资源 - 如果server意外崩溃没有执行
unlink,共享内存会残留在系统中,你可以到Linux的/dev/shm目录下手动删除名称为test_uint_np、test_float_np的残留文件
内容的提问来源于stack exchange,提问作者ravi
相关产品推荐
相关产品推荐

