news 2026/6/24 0:23:02

进程间通信--共享内存

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
进程间通信--共享内存

共享内存的基本原理

1. 核心步骤

要在 Linux 中使用 System V 共享内存,通常遵循以下“四步走”:

  1. 创建/获取 (Create/Get):向内核申请一块共享内存,就像malloc一样,但这是内核管理的。
    • 系统调用:shmget
  1. 关联 (Attach):把这块物理内存“挂接”到当前进程的虚拟地址空间(堆栈之间)。挂接后,这就变成了你进程内的一个指针。
    • 系统调用:shmat(Shared Memory Attach)
  1. 使用 (Use):像使用普通数组或指针一样读写数据。
  2. 去关联 (Detach):用完了,把这块内存从页表中去掉(断开联系)。
    • 系统调用:shmdt(Shared Memory Detach)
  1. 删除 (Control/Remove):如果所有进程都不用了,需要请求内核释放这块物理内存。
    • 系统调用:shmctl
2. 这里的“坑”:生命周期

这是一个极其重要的概念,也是和管道最大的区别。

  • 管道:进程退出了,管道就自动销毁了(匿名管道),或者没人用时虽然文件在但数据清空了(命名管道)。
  • 共享内存随内核 (Kernel Persistence)
    • 如果你创建了共享内存,进程 A 退出了,进程 B 也退出了,但这块内存依然存在于内核中
    • 除非你显式调用代码删除它,或者重启操作系统,否则它会一直占用物理内存。
    • 后果:调试代码时如果程序崩溃没来得及清理,你会发现内存泄漏,下次启动程序可能报错“File exists”。

系统调用详解

为了写代码,我们需要先认识这几个核心函数的参数。这部分比mkfifo复杂,涉及到一个新的概念:Key

1.ftok—— 生成唯一标识符

怎么让两个无关的进程(Server 和 Client)找到同一个共享内存呢?

  • 命名管道:靠文件路径(唯一)。
  • 共享内存:靠Key 值(唯一)。

我们需要一个算法,把一个文件路径和一个项目 ID 转换成一个唯一的数字 Key。

#include <sys/types.h> #include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id);
  • pathname:一个存在的文件路径(通常用当前目录.)。
  • proj_id:一个整数(通常写个字符,如'a')。
  • 返回值:成功返回生成的key_t,两端只要传入相同的路径和 ID,就能得到相同的 Key。
2.shmget—— 创建共享内存
#include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);
  • key:刚才ftok生成的那个 Key。
  • size:申请多少字节?(建议是 4KB 的整数倍,因为操作系统按页分配内存,如果你申请 4097 字节,OS 实际会分配 8KB,但你只能用 4097)。
  • shmflg:标志位和权限。
    • IPC_CREAT:不存在就创建,存在就获取。
    • IPC_EXCL:配合IPC_CREAT使用,如果存在则报错(用于确保我是第一个创建的)。
    • 权限:类似文件权限,如0666
  • 返回值:成功返回shmid(共享内存 ID),类似文件描述符fd;失败返回 -1。
3.shmat—— 挂接
void *shmat(int shmid, const void *shmaddr, int shmflg);
  • shmidshmget返回的 ID。
  • shmaddr:想挂载到虚拟内存的哪个地址?通常传NULL,让内核自己找个风水宝地。
  • shmflg:读写模式,默认为 0(可读写)。
  • 返回值:成功返回共享内存的首地址(void*),失败返回 -1。
4.shmctl—— 控制/删除
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • cmd:常用IPC_RMID(Remove ID),标记删除。
  • 注意IPC_RMID只是标记删除。只有当连接这块内存的所有进程都shmdt(断开)后,物理内存才会真正释放。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 20:48:38

【Leetcode】997. Find the Town Judge

题目地址&#xff1a; https://leetcode.com/problems/find-the-town-judge/description/ 给定nnn个点&#xff0c;编号1∼n1\sim n1∼n&#xff0c;再给定若干条连接两个点的有向边&#xff0c;题目保证不出现自环和平行边。找出满足以下要求的点&#xff1a; 所有别的点都…

作者头像 李华
网站建设 2026/6/23 20:48:23

百度网盘提取码智能获取终极指南

百度网盘提取码智能获取终极指南 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘分享链接的提取码而烦恼吗&#xff1f;面对加密分享和隐藏密码&#xff0c;传统的人工查找方式既费时又低效。baidupankey工具的…

作者头像 李华
网站建设 2026/6/23 20:47:47

Linux桌面美化终极指南:让你的工作环境焕然一新

Linux桌面美化终极指南&#xff1a;让你的工作环境焕然一新 【免费下载链接】Awesome-Linux-Software &#x1f427; A list of awesome Linux softwares 项目地址: https://gitcode.com/GitHub_Trending/aw/Awesome-Linux-Software 厌倦了千篇一律的Linux桌面&#xf…

作者头像 李华
网站建设 2026/6/23 23:08:24

ThingsGateway:构建智能物联网设备管理平台的完整指南

ThingsGateway&#xff1a;构建智能物联网设备管理平台的完整指南 【免费下载链接】ThingsGateway ThingsGateway 是基于Net6/7/8的跨平台边缘采集网关&#xff0c;提供底层PLC通讯库&#xff0c;通讯调试软件等。 项目地址: https://gitcode.com/gh_mirrors/th/ThingsGatewa…

作者头像 李华
网站建设 2026/6/23 1:44:16

软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(17)

接前一篇文章:软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(16) 所属章节: 第15章. 面向服务架构设计理论与实践 第8节 SOA的设计模式 15.8 SOA的设计模式 15.8.2 企业服务总线模式 在企业基于SOA实施EAI、B2B和BMP的过程中,如果采用点对点的集成方式,…

作者头像 李华
网站建设 2026/6/23 12:32:34

重新定义Grafana管理:MCP协议集成的智能监控新范式

重新定义Grafana管理&#xff1a;MCP协议集成的智能监控新范式 【免费下载链接】mcp-grafana MCP server for Grafana 项目地址: https://gitcode.com/gh_mirrors/mc/mcp-grafana 在数据监控的世界里&#xff0c;你是否曾面临这样的困境&#xff1a;面对数十个仪表板&am…

作者头像 李华