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

Linux下跨进程共享内存:能否用P1虚拟地址让P2写入?

方案不可行,原因及正确实现方式

你的方案完全不可行,核心原因是:Linux下每个进程拥有独立的虚拟地址空间,P1的虚拟地址仅在P1的地址空间内有效,在P2中要么是未映射的无效地址(触发段错误SIGSEGV),要么指向P2地址空间中完全无关的物理内存区域,根本无法写入到P1创建的共享内存缓冲区里。

正确的跨进程共享内存实现方式

在Linux下,跨进程共享内存需要依赖内核提供的共享内存机制,让两个进程将同一块物理内存映射到各自的虚拟地址空间,常用的两种方式如下:

方式一:POSIX有名共享内存(推荐)

P1 步骤:

  1. 调用shm_open创建一个有名共享内存对象,例如:
    int shm_fd = shm_open("/my_1mb_shm", O_CREAT | O_RDWR, 0666);
    
  2. 用ftruncate设置共享内存大小为1MB:
    ftruncate(shm_fd, 1024 * 1024);
    
  3. 调用mmap将共享内存映射到P1的虚拟地址空间:
    void *buf = mmap(NULL, 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    
  4. 保持P1运行,不要关闭shm_fd或解除映射(直到不需要共享内存为止)。

P2 步骤:

  1. 调用shm_open打开同一个有名共享内存对象:
    int shm_fd = shm_open("/my_1mb_shm", O_RDWR, 0666);
    
  2. 同样调用mmap将共享内存映射到P2的虚拟地址空间(这个地址和P1的虚拟地址大概率不同,但指向同一块物理内存):
    void *buf = mmap(NULL, 1024 * 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    
  3. 向buf指向的地址写入数据,完成后解除映射并关闭文件描述符:
    munmap(buf, 1024 * 1024);
    close(shm_fd);
    
  4. 终止P2,此时P1可以从自己的buf地址读取到P2写入的数据。

方式二:System V共享内存

P1 步骤:

  1. 调用shmget创建共享内存段,指定key、大小1MB和权限:
    key_t key = ftok("/some_existing_file", 'R'); // 用现有文件生成唯一key
    int shm_id = shmget(key, 1024 * 1024, IPC_CREAT | 0666);
    
  2. 调用shmat将共享内存段映射到P1的虚拟地址空间:
    void *buf = shmat(shm_id, NULL, 0);
    
  3. 保持P1运行。

P2 步骤:

  1. 用同一个key调用shmget获取共享内存段:
    key_t key = ftok("/some_existing_file", 'R');
    int shm_id = shmget(key, 1024 * 1024, 0666);
    
  2. 调用shmat映射到P2的虚拟地址空间:
    void *buf = shmat(shm_id, NULL, 0);
    
  3. 写入数据后,调用shmdt解除映射:
    shmdt(buf);
    
  4. 终止P2,P1即可读取数据。

关键注意点

  • 无论哪种方式,两个进程都必须通过内核提供的接口来关联同一块物理内存,绝对不能直接使用其他进程的虚拟地址。
  • 使用POSIX共享内存时,若不再需要共享内存,要调用shm_unlink删除有名对象,避免系统资源残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:45:54