news 2026/3/30 16:02:24

Linux进程间通信mmap与共享内存对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux进程间通信mmap与共享内存对比

mmap 与 System V 共享内存对比

概述

mmap 和 System V 共享内存都是 Linux 中用于进程间通信(IPC)的机制, 两者都允许多个进程共享同一块物理内存, 实现零拷贝的高效通信. 本文档从使用方式、特点、实现机制等多个维度进行详细对比.

使用方式对比

API 对比

mmap 相关 API
#include<sys/mman.h>// 创建内存映射void*mmap(void*addr,size_tlength,intprot,intflags,intfd,off_toffset);// 取消映射intmunmap(void*addr,size_tlength);// 同步到文件intmsync(void*addr,size_tlength,intflags);

特点:

  • 统一的 API, 既可用于文件映射, 也可用于匿名映射
  • 需要文件描述符(匿名映射时使用 -1)
  • 直接返回虚拟地址指针
System V 共享内存 API
#include<sys/shm.h>// 创建/获取共享内存段intshmget(key_tkey,size_tsize,intshmflg);// 附加到进程地址空间void*shmat(intshmid,constvoid*shmaddr,intshmflg);// 分离共享内存intshmdt(constvoid*shmaddr);// 控制操作(删除、获取信息等)intshmctl(intshmid,intcmd,structshmid_ds*buf);

特点:

  • 专门的 IPC API, 需要多个步骤
  • 使用键值(key)标识共享内存段
  • 需要显式的 attach/detach 操作

使用流程对比

mmap 使用流程

文件映射方式:

// 1. 打开文件intfd=open("shared.dat",O_RDWR|O_CREAT,0666);ftruncate(fd,size);// 2. 创建映射void*addr=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);// 3. 使用映射区域memcpy(addr,data,size);// 4. 同步(可选)msync(addr,size,MS_SYNC);// 5. 取消映射munmap(addr,size);close(fd);

匿名映射方式:

// 1. 创建匿名映射void*addr=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);// 2. 使用(父子进程通过 fork 共享)// 3. 取消映射munmap(addr,size);
System V 共享内存使用流程
// 1. 生成键值key_tkey=ftok(".",'s');// 2. 创建/获取共享内存段intshmid=shmget(key,size,IPC_CREAT|0666);// 3. 附加到进程地址空间void*addr=shmat(shmid,NULL,0);// 4. 使用共享内存memcpy(addr,data,size);// 5. 分离共享内存shmdt(addr);// 6. 删除共享内存段(可选, 通常由一个进程负责)shmctl(shmid,IPC_RMID,NULL);

标识方式对比

特性mmapSystem V 共享内存
标识方式文件路径 + 文件描述符键值(key) + shmid
键值生成不需要(使用文件路径)需要ftok()IPC_PRIVATE
跨进程共享通过文件路径通过键值
持久性文件映射持久, 匿名映射不持久显式删除前持久

特点对比

功能特性对比

特性mmapSystem V 共享内存
文件关联可以映射文件, 也可以匿名映射不关联文件, 纯内存
持久性文件映射持久, 匿名映射不持久显式删除前持久
同步到文件支持msync()同步到文件不支持文件同步
按需加载支持, 利用虚拟内存按需加载不支持, 一次性分配
大文件处理适合处理大文件不适合, 需要一次性分配全部内存
灵活性高, 可以映射文件、设备、匿名区域中, 只能创建纯内存段
地址选择可以指定地址或让系统选择可以指定地址或让系统选择

性能特点对比

性能指标mmapSystem V 共享内存
零拷贝✅ 是✅ 是
直接内存访问✅ 是✅ 是
延迟低(直接内存访问)极低(直接内存访问)
吞吐量高(零拷贝)极高(零拷贝)
CPU占用
内存占用按需加载, 节省内存一次性分配, 占用固定内存
缺页处理支持, 按需加载文件内容不支持, 内存已分配

同步机制需求

两者都需要用户空间的同步机制:

同步机制mmapSystem V 共享内存
内核保护❌ 无❌ 无
需要同步✅ 是✅ 是
常用同步方式信号量、互斥锁、原子操作信号量、互斥锁、原子操作
同步复杂度相同相同

实现机制对比

内核实现对比

mmap 实现机制

核心数据结构:

  • vm_area_struct(VMA): 虚拟内存区域描述符
  • mm_struct: 进程地址空间描述符
  • file: 文件对象(文件映射时)

实现路径:

sys_mmap2 → do_mmap_pgoff → - 地址选择(get_unmapped_area) - VMA 创建和初始化 - 文件映射(file->f_op->mmap) 或匿名映射(shmem_zero_setup) - VMA 插入到进程地址空间

关键特点:

  • 基于虚拟内存管理(VMA)
  • 文件映射使用页缓存(page cache)
  • 匿名映射使用 shmem 文件系统
  • 支持按需加载(缺页处理)
System V 共享内存实现机制

核心数据结构:

  • shmid_kernel: 共享内存段描述符
  • shmem_inode_info: shmem 文件系统 inode
  • kern_ipc_perm: IPC 权限和键值管理

实现路径:

sys_shmget → newseg → - 创建 shmid_kernel - 创建 shmem 文件(shmem_file_setup) - 安装到 IPC ID 表 sys_shmat → do_shmat → - 权限检查 - 调用 do_mmap_pgoff 映射 shm_file - 更新附加计数

关键特点:

  • 基于 IPC 框架(键值、权限管理)
  • 内部使用 shmem 文件系统
  • 最终通过 mmap 机制映射到进程地址空间
  • 需要显式的 attach/detach 操作

内存管理对比

方面mmapSystem V 共享内存
内存分配时机按需分配(缺页时)创建时一次性分配
物理页管理页缓存或匿名页shmem 文件系统页
换入换出支持(除非 MAP_LOCKED)支持(除非 SHM_LOCK)
内存锁定MAP_LOCKED 标志SHM_LOCK 命令
页表管理通过 VMA 管理通过 VMA 管理(内部使用 mmap)

文件系统依赖

特性mmapSystem V 共享内存
文件系统文件映射依赖文件系统, 匿名映射使用 shmem内部使用 shmem, 用户不可见
文件可见性文件映射时文件可见文件不可见(内部使用)
文件同步支持 msync 同步到文件不支持文件同步

适用场景对比

mmap 适用场景

适合:

  • 大文件处理(按需加载)
  • 需要文件持久化的场景
  • 数据库、缓存等需要文件映射的应用
  • 需要高效文件 I/O 的场景
  • 父子进程通过 fork 共享内存

不适合:

  • 简单的进程间通信(管道更合适)
  • 不需要文件关联的纯内存共享

System V 共享内存适用场景

适合:

  • 大数据量传输
  • 对性能要求极高的场景
  • 需要频繁通信的场景
  • 不需要文件关联的纯内存共享
  • 需要显式生命周期管理的场景

不适合:

  • 需要文件持久化的场景
  • 大文件处理(需要一次性分配全部内存)
  • 需要按需加载的场景

优缺点对比

mmap 优缺点

优点:

  1. ✅ 功能强大: 既可以映射文件, 也可以匿名映射
  2. ✅ 按需加载: 利用虚拟内存机制, 节省内存
  3. ✅ 文件同步: 支持同步到文件, 数据持久化
  4. ✅ 大文件处理: 适合处理大文件, 无需一次性加载
  5. ✅ 灵活性高: 可以映射文件、设备、匿名区域
  6. ✅ 标准 POSIX API: 跨平台兼容性好

缺点:

  1. ❌ API 相对复杂: 需要理解虚拟内存概念
  2. ❌ 文件依赖: 文件映射依赖文件系统
  3. ❌ 匿名映射共享: 父子进程共享需要 fork, 独立进程共享需要文件
  4. ❌ 同步机制: 需要用户空间同步机制

System V 共享内存优缺点

优点:

  1. ✅ 性能极高: 零拷贝, 直接内存访问
  2. ✅ 简单直接: 专门的 IPC API, 语义清晰
  3. ✅ 持久性: 显式删除前一直存在
  4. ✅ 独立进程通信: 不要求进程间有亲缘关系
  5. ✅ 生命周期管理: 显式的创建、附加、分离、删除

缺点:

  1. ❌ 内存占用: 一次性分配全部内存, 不能按需加载
  2. ❌ 无文件关联: 不支持文件持久化
  3. ❌ 键值管理: 需要管理键值, 可能冲突
  4. ❌ 系统限制: 受系统对共享内存大小、数量限制
  5. ❌ 资源清理: 需要显式删除, 否则会一直占用
  6. ❌ 非 POSIX: System V 特有, 跨平台兼容性差

代码示例对比

相同功能的不同实现

场景: 多进程共享计数器

使用 mmap (文件映射):

// 创建共享文件intfd=open("counter.dat",O_RDWR|O_CREAT,0666);ftruncate(fd,sizeof(int));// 映射int*counter=mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);// 使用(*counter)++;// 清理munmap(counter,sizeof(int));close(fd);unlink("counter.dat");

使用 System V 共享内存:

// 创建共享内存key_tkey=ftok(".",'c');intshmid=shmget(key,sizeof(int),IPC_CREAT|0666);// 附加int*counter=shmat(shmid,NULL,0);// 使用(*counter)++;// 清理shmdt(counter);shmctl(shmid,IPC_RMID,NULL);

功能差异示例

mmap 独有: 文件映射和同步
// mmap 可以映射文件并同步intfd=open("data.txt",O_RDWR);void*addr=mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);// 修改数据strcpy(addr,"Hello");// 同步到文件msync(addr,4096,MS_SYNC);munmap(addr,4096);close(fd);

System V 共享内存不支持文件映射和同步.

System V 共享内存独有: 显式生命周期管理
// System V 共享内存可以独立于进程存在key_tkey=ftok(".",'s');intshmid=shmget(key,4096,IPC_CREAT|0666);// 进程 A 使用void*addr1=shmat(shmid,NULL,0);// ... 使用 ...shmdt(addr1);// 进程 A 退出, 但共享内存段仍然存在// 进程 B 可以继续使用同一个共享内存段void*addr2=shmat(shmid,NULL,0);// ... 使用 ...shmdt(addr2);// 最后删除shmctl(shmid,IPC_RMID,NULL);

mmap 文件映射虽然也持久, 但需要文件存在.

选择建议

选择 mmap 的情况

  1. ✅ 需要文件持久化
  2. ✅ 需要处理大文件(按需加载)
  3. ✅ 需要文件 I/O 和内存访问的统一接口
  4. ✅ 需要跨平台兼容性(POSIX 标准)
  5. ✅ 父子进程通过 fork 共享内存

选择 System V 共享内存的情况

  1. ✅ 纯内存共享, 不需要文件关联
  2. ✅ 需要显式的生命周期管理
  3. ✅ 需要独立于进程存在的共享内存
  4. ✅ 大数据量传输, 性能要求极高
  5. ✅ 不需要按需加载, 内存充足

两者都可以的情况

  • 简单的进程间数据共享
  • 需要零拷贝的高性能通信
  • 多进程共享数据结构

在这种情况下, 可以根据具体需求选择:

  • 如果需要文件持久化 → mmap
  • 如果需要显式生命周期管理 → System V 共享内存
  • 如果需要跨平台 → mmap
  • 如果只需要纯内存共享 → System V 共享内存

总结

mmap 和 System V 共享内存都是高效的进程间通信机制, 两者都实现了零拷贝的直接内存访问. 主要区别在于:

  1. 功能定位: mmap 更通用(文件映射 + 匿名映射), System V 共享内存专门用于 IPC
  2. 内存管理: mmap 支持按需加载, System V 共享内存一次性分配
  3. 持久化: mmap 支持文件持久化, System V 共享内存不支持
  4. API 设计: mmap 统一 API, System V 共享内存专门的 IPC API
  5. 跨平台: mmap 是 POSIX 标准, System V 共享内存是 System V 特有

选择时应该根据具体需求: 需要文件持久化或大文件处理选择 mmap, 需要纯内存共享或显式生命周期管理选择 System V 共享内存.

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 20:13:07

如何用AI自动化解决Mac安全策略配置问题

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个MacOS自动化工具&#xff0c;能够自动执行以下操作&#xff1a;1) 从MacOS恢复模式启动&#xff1b;2) 导航到安全策略设置&#xff1b;3) 将安全策略更改为完整安全。要求…

作者头像 李华
网站建设 2026/3/27 17:08:39

电商后台管理系统:Vue脚手架实战指南

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个电商后台管理系统的Vue脚手架模板&#xff0c;要求包含&#xff1a;1. 多角色权限控制模块&#xff1b;2. 商品管理CRUD界面&#xff1b;3. 数据可视化仪表盘&#xff1b;4…

作者头像 李华
网站建设 2026/3/27 17:35:22

传统vsAI设计:电压跟随器开发效率提升300%的秘诀

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请对比传统设计流程和AI辅助流程开发电压跟随器的效率差异。传统流程要求&#xff1a;1. 手动绘制电路图&#xff1b;2. 计算参数&#xff1b;3. 搭建仿真&#xff1b;4. 迭代优化。…

作者头像 李华
网站建设 2026/3/27 19:52:46

3小时打造跨文化社交应用原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个跨文化社交应用原型&#xff0c;包含核心功能&#xff1a;1. 用户注册/登录&#xff1b;2. 多语言聊天界面&#xff1b;3. 基本个人资料页&#xff1b;4. 简单的文化提…

作者头像 李华
网站建设 2026/3/26 19:08:15

AI教你玩转Win10截图:快捷键+智能识别

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个Win10截图辅助工具&#xff0c;功能包括&#xff1a;1.自动检测系统快捷键设置 2.截图后调用OCR API识别文字 3.支持一键翻译识别内容 4.自动分类存储截图 5.生成操作日志报…

作者头像 李华
网站建设 2026/3/27 20:39:15

Beyond Compare 过滤干扰项设置_android项目文件过滤设置

Beyond Compare 比对代码时&#xff0c;需要过滤干扰项&#xff0c;让比对时更加清晰 一下以Android项目过滤例 排除文件 *.iml local.properties AndroidManifest_target.xml排除文件夹 .git .svn .gradle .idea build release .cxx

作者头像 李华