You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程作业间静态数据共享优化:降低内存占用方案咨询

多进程绘图静态数据内存优化方案

针对多进程处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:12:56