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

Python使用multiprocessing.shared_memory共享numpy数组报段错误139如何解决

问题原因

你遇到的段错误(SIGSEGV)核心原因是共享内存的生命周期管理错误,具体可以拆解为两点:

  1. 你在decode_nd_arr_list函数中创建的SharedMemory实例是循环内的局部变量,函数返回后没有任何变量持有这些实例的引用,Python的垃圾回收机制会自动销毁这些SharedMemory对象,对象销毁时会自动解除当前进程对共享内存的地址映射。而你返回的numpy数组依然指向已经被解除映射的内存地址,访问时就会触发段错误。
  2. numpy数组使用buffer参数创建时,只会持有传入的buffer对象(也就是shm.buf这个memoryview)的引用,不会持有SharedMemory实例本身的引用,只要SharedMemory实例被回收,哪怕memoryview还存在,对应的内存地址也已经无效。

修复方案

只需要调整decode_nd_arr_list的返回值,把对应的SharedMemory实例也一并返回,保证在使用数组的周期内这些实例不会被回收即可,同时你可以根据自己的业务场景决定是在SharedMemoryManager的上下文内完成所有操作,还是手动管理共享内存的释放。

修改后的可运行代码如下:

from typing import List, Tuple
import numpy as np
from multiprocessing.shared_memory import SharedMemory
from multiprocessing.managers import SharedMemoryManager


def encode_nd_arr_list(
        smm: SharedMemoryManager,
        nd_arr_list: List[np.ndarray]
):
    shm_name_list = []
    shape, dtype = nd_arr_list[0].shape, nd_arr_list[0].dtype
    for nd_arr in nd_arr_list:
        shm = smm.SharedMemory(size=nd_arr.nbytes)
        shm_arr = np.ndarray(shape=shape, dtype=dtype, buffer=shm.buf)
        np.copyto(shm_arr, nd_arr)
        shm_name_list.append(shm.name)
    return shm_name_list, shape, dtype


def decode_nd_arr_list(
        shm_name_list: List[str],
        shape: Tuple[int],
        dtype: np.dtype
):
    nd_array_list = []
    # 新增列表保存SharedMemory实例,避免被GC回收
    shm_list = []
    for shm_name in shm_name_list:
        shm = SharedMemory(shm_name)
        nd_arr = np.ndarray(shape=shape, dtype=dtype, buffer=shm.buf)
        nd_array_list.append(nd_arr)
        shm_list.append(shm)
    # 同时返回数组列表和对应的共享内存实例列表
    return nd_array_list, shm_list


if __name__ == '__main__':
    arr = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5]])
    nd_arr_list = [arr, arr + 1, arr + 2]
    print("原始数组列表:", nd_arr_list)
    with SharedMemoryManager() as smm:
        shm_name_list, shape, dtype = encode_nd_arr_list(smm, nd_arr_list)
        res, shm_list = decode_nd_arr_list(shm_name_list, shape, dtype)
        print("------------")
        print("还原后的数组列表:", res)
    # 出了with块后SharedMemoryManager会自动释放所有共享内存,此时res对应的内存已失效,不要再访问

如果你需要在SharedMemoryManager上下文之外使用共享内存,可以放弃使用管理器,手动创建SharedMemory实例,使用完毕后主动调用close()和unlink()方法释放资源即可。

内容的提问来源于stack exchange,提问作者maplemaple

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:54:03