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

共享内存中动态分配内存为何会重置为初始化值?

问题原因

核心问题在于共享内存仅存储了SharedMemory结构体本身,而结构体中的solutionVector指针指向的是进程私有堆内存,不属于共享内存区域:

  • 主进程调用initializeSharedMemory时,createVector和calloc分配的是主进程自身的私有堆内存,这块内存不会被共享给子进程。
  • 子进程fork后,共享内存里的solutionVector指针值会被复制,但该指针在子进程地址空间中指向的是子进程自己的私有堆(fork操作会复制父进程的堆空间),子进程更新的是自己私有堆内的vector数据,这些修改无法同步到主进程的私有堆。
  • 主进程最终打印时,访问的是自己初始分配的私有堆内的vector,因此显示的是初始全0值。
  • 输出中distance:21是正确的,因为bestSolutionDistance是结构体内部的int类型变量,属于共享内存区域,所以能正常同步。

解决方法

提供两种针对性修正方案:

方案1:将Vector内容嵌入共享内存结构体(固定大小场景)

如果Vector的大小是提前确定的,直接修改SharedMemory结构体,用数组替代指针:

// 根据实际业务调整最大向量长度
#define MAX_VECTOR_SIZE 100
typedef struct{
    int bestSolutionDistance;
    int BestSolutionFoundByProcess;
    int BestSolutionFoundInIterations;
    int solutionVector[MAX_VECTOR_SIZE]; // 直接嵌入数组
} SharedMemory;

修改initializeSharedMemory函数,直接初始化共享内存内的数组:

void initializeSharedMemory(SharedMemoryPtr sharedMemoryPtr, int size) {
    sharedMemoryPtr->bestSolutionDistance = 1e9; 
    sharedMemoryPtr->BestSolutionFoundByProcess = -1; 
    sharedMemoryPtr->BestSolutionFoundInIterations = -1;
    // 直接初始化共享内存中的数组
    memset(sharedMemoryPtr->solutionVector, 0, size * sizeof(int));
}

主进程计算共享内存大小直接使用sizeof(SharedMemory)即可。

方案2:让指针指向共享内存内部区域(动态大小场景)

如果Vector大小是动态的,需要把Vector的内存也纳入共享内存范围:

  1. 计算共享内存总大小:结构体大小 + Vector所需内存
int vectorSize = distanceMatrix->size;
size_t sharedMemoryTotalSize = sizeof(SharedMemory) + vectorSize * sizeof(int);
int shm_fd = createOrOpenSharedMemory(SHM_NAME, sharedMemoryTotalSize);
  1. 映射共享内存后,让solutionVector指向共享内存结构体后的区域:
sharedMemoryAllocatedPtr = mapSharedMemory(shm_fd, sharedMemoryTotalSize);
// 让指针指向共享内存内部的数组区域
sharedMemoryAllocatedPtr->solutionVector = (int*)((char*)sharedMemoryAllocatedPtr + sizeof(SharedMemory));
  1. 修改initializeSharedMemory函数,直接初始化共享内存内的数组:
void initializeSharedMemory(SharedMemoryPtr sharedMemoryPtr, int size) {
    sharedMemoryPtr->bestSolutionDistance = 1e9; 
    sharedMemoryPtr->BestSolutionFoundByProcess = -1; 
    sharedMemoryPtr->BestSolutionFoundInIterations = -1;
    memset(sharedMemoryPtr->solutionVector, 0, size * sizeof(int));
}

这样solutionVector指向的是共享内存的一部分,所有进程访问的是同一块内存,修改会实时同步。

额外注意事项

  • 多进程场景下,必须用信号量等同步机制保护共享内存的读写,避免数据竞争。
  • 原代码中calloc分配的dataTest不再需要,需同步修改initializeVector函数,使其直接操作solutionVector指向的共享内存数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 05:40:31