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

父进程动态分配的内存块无法共享给子进程问题咨询

问题核心原因

Linux 系统中fork()创建子进程后,父子进程拥有完全独立的虚拟地址空间,遵循写时复制机制:

  • fork执行完成的初始阶段,父子进程的相同虚拟地址会映射到同一块物理内存,此时双方读操作共享同一份数据,所以你观察到子进程可以正常读取指针指向的数值,且两边打印的指针虚拟地址完全相同。
  • 当任意一方尝试修改该内存内容时,内核会单独复制一份物理内存页给修改方使用,修改操作仅作用在自身地址空间内,完全不会影响对方的内存数据,这就是父进程感知不到子进程修改的根本原因。

另外你的代码还存在一个未定义行为隐患:子进程中定义int *value = NULL;后直接调用read(pipeVariable[0], value, sizeof(int));,相当于往空指针指向的内存地址写入数据,大概率会触发段错误,能正常运行属于概率性的异常情况。正确写法应该是读取父进程传递的指针值到value变量本身的存储地址,即read(pipeVariable[0], &value, sizeof(int*));。

可用解决方案

如果你需要实现父子进程内存共享,可选择以下三种常用方案:

方案1:使用mmap创建匿名共享映射(改造成本最低)

将父进程中malloc分配内存的逻辑替换为mmap创建共享映射即可,修改后的完整代码示例:

#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/mman.h>

int main() {
    int pipeVariable[2] = {0};
    pipe(pipeVariable);
    int x = fork();

    if(x == -1){
        perror("Error spawning child process");
        exit(1);
    }
    else if(x == 0){
        int *value = NULL;
        read(pipeVariable[0], &value, sizeof(int*));
        printf("Child \nMemory block : %p\nValue : %d\n", value, *value);
        printf("Child Changed the value\n");
        *value = 10;
        printf("Child \nMemory block : %p\nValue : %d\n", value, *value);
        close(pipeVariable[1]);
        close(pipeVariable[0]);
        exit(0);
    }
    else{
        int *testVariable = mmap(NULL, sizeof(int), 
                                PROT_READ | PROT_WRITE, 
                                MAP_SHARED | MAP_ANONYMOUS, 
                                -1, 0);
        *testVariable = 1000;
        printf("Parent \nMemory block : %p\nValue : %d\n", testVariable, *testVariable);
        write(pipeVariable[1], &testVariable, sizeof(int*));     
        wait(NULL);   
        printf("Parent \nMemory block : %p\nValue : %d\n", testVariable, *testVariable);
        munmap(testVariable, sizeof(int));
        close(pipeVariable[1]);
        close(pipeVariable[0]);
    }
    return 0;
}

方案2:使用System V共享内存

调用shmget、shmat、shmdt系列系统接口创建全局共享内存段,父子进程分别挂载该内存段即可实现数据共享。

方案3:通过管道回传修改结果

如果不需要实时共享内存,可在子进程修改完数值后,通过管道将新值反向发送给父进程,父进程读取后更新本地变量即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:18:03