多进程作业间静态数据共享优化:降低内存占用方案咨询
多进程绘图静态数据内存优化方案
针对多进程处理12个区域绘图时内存占用过高的问题,核心是避免每个子进程复制一份静态数据(da、x、y数组、Shapefile),以下是几种实用的共享/复用方案:
1. 用共享内存存储大数组
对于rioxarray生成的da、x、y这类numpy数组,使用multiprocessing.shared_memory实现进程间内存共享,彻底避免重复复制大数组:
from multiprocessing import shared_memory import numpy as np import rioxarray # 主进程创建共享内存并写入数据 def create_shared_array(arr): shm = shared_memory.SharedMemory(create=True, size=arr.nbytes) shared_arr = np.ndarray(arr.shape, dtype=arr.dtype, buffer=shm.buf) shared_arr[:] = arr[:] return shm, shared_arr # 子进程通过共享内存名称重建数组 def get_shared_array(shm_name, shape, dtype): shm = shared_memory.SharedMemory(name=shm_name) return np.ndarray(shape, dtype=dtype, buffer=shm.buf) # 主进程示例代码 if __name__ == "__main__": da = rioxarray.open_rasterio("your_data.tif").values shm_da, _ = create_shared_array(da) shm_x, _ = create_shared_array(x) shm_y, _ = create_shared_array(y) # 传递共享内存标识、数组元数据给子进程 process_args = [ (shm_da.name, da.shape, da.dtype, shm_x.name, x.shape, x.dtype, shm_y.name, y.shape, y.dtype, "shapefile_path.shp", region) for region in regions ] # 启动多进程执行绘图任务... # 所有进程结束后释放共享内存 for shm in [shm_da, shm_x, shm_y]: shm.close() shm.unlink()
2. 子进程延迟加载Shapefile
不要在主进程加载Shapefile后传递对象,而是直接传递文件路径,让子进程按需加载。这样避免主进程将大体积的Shapefile对象复制到所有子进程:
def plot_region(region, da_shared, shapefile_path): # 子进程内加载Shapefile import geopandas as gpd shape_data = gpd.read_file(shapefile_path) # 结合共享数组da_shared和shape_data完成当前区域绘图...
3. 进程池初始化时复用静态数据
使用multiprocessing.Pool的initializer参数,在子进程启动时一次性加载静态资源,每个子进程仅加载一次,而非每个任务复制一次:
from multiprocessing import Pool import geopandas as gpd import numpy as np # 全局变量存储静态数据(子进程可见) global_da = None global_shape = None def init_worker(shm_da_name, da_shape, da_dtype, shapefile_path): global global_da, global_shape # 从共享内存获取数组 shm_da = shared_memory.SharedMemory(name=shm_da_name) global_da = np.ndarray(da_shape, dtype=da_dtype, buffer=shm_da.buf) # 加载Shapefile global_shape = gpd.read_file(shapefile_path) def plot_func(region): # 直接使用全局变量完成当前区域绘图 # 处理region对应的地图范围... pass if __name__ == "__main__": da = ... # 你的数组数据 shm_da, _ = create_shared_array(da) shape_path = "your_shapefile.shp" regions = [...] # 12个区域列表 # 进程数建议设为CPU核心数,避免资源过载 with Pool(processes=8, initializer=init_worker, initargs=(shm_da.name, da.shape, da.dtype, shape_path)) as pool: pool.map(plot_func, regions) # 释放共享内存 shm_da.close() shm_da.unlink()
4. 控制进程数量
不要一次性启动12个进程(与区域数相等),建议将进程数设置为CPU核心数(比如4-8),让进程复用处理多个区域,减少同时加载的资源副本数量。
内容的提问来源于stack exchange,提问作者TornadoEric
相关产品推荐
相关产品推荐

