news 2026/8/25 15:15:25

共享内存呀

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
共享内存呀

共享内存(Shared Memory)是IPC 进程间通信方式之一,原理:在内核开辟一块物理内存,多个进程将这块内存映射到自己的虚拟地址空间,直接读写内存,无需内核拷贝数据,速度最快;但没有自带同步互斥,一般要搭配信号量、互斥锁使用。

完整函数链路:ftok()shmget()shmat()→ 读写内存 →shmdt()shmctl()

1. ftok —— 生成 IPC 键值 key_t

#include <sys/types.h> #include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

参数说明

  1. pathname存在的文件路径(必须真实存在,一般用当前目录.
  2. proj_id:项目 ID,0~255 之间的整数(常用字母,如'a'

返回值

  • 成功:返回key_t类型键值(用于 shmget、msgget、semget)
  • 失败:-1,设置 errno

原理

ftok 根据 文件设备号、文件 inode、proj_id 组合算出唯一 key; ⚠️ 注意:文件删除重建后,inode 变化,ftok 结果会变

注意:用ipcs查看

2. shmget —— 创建 / 获取共享内存段(建立key和stimid的关系)

#include <sys/ipc.h> #include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

参数

  1. key:ftok 得到的键值;特殊值IPC_PRIVATE代表私有共享内存(只用于亲缘进程)
  2. size:共享内存大小,建议 4k 对齐(内存页大小)
  3. shmflg:权限 + 创建标志
    • IPC_CREAT:不存在则创建,存在直接获取
    • IPC_EXCL:搭配 IPC_CREAT,存在则报错
    • 权限位:0666类似文件权限

一般就是IPC_CREAT|0666

返回值

  • 成功:shmid 共享内存标识符(int),后续操作都用它
  • 失败:-1

3. shmat —— 挂载(映射)共享内存到进程虚拟地址(建立映射--获得地址)

attach:把内核共享内存映射到当前进程地址空间,得到可用指针。

void *shmat(int shmid, const void *shmaddr, int shmflg);

参数

  1. shmid:要映射的本地内存
  2. shmaddr:本地可用地址 一般不确定--》NULL
  3. shmflg:挂载属性
    • 0:可读可写
    • SHM_RDONLY:只读挂载

返回值

  • 成功:返回映射后的起始虚拟地址指针(void*,强制转换使用)
  • 失败:(void *)-1

4. shmdt —— 脱离共享内存(解除映射)

detach:进程用完共享内存,断开映射;不会删除内核中的共享内存段!

int shmdt(const void *shmaddr);

参数

shmaddr:shmat 返回的映射起始地址

返回值

成功返回 0;失败 -1

eg:if(shmdt(p)<0)

5. shmctl —— 共享内存控制(获取信息、删除、设置属性)

control,多功能控制函数,最常用:IPC_RMID 删除共享内存

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

参数

  1. shmid:共享内存 id
  2. cmd:控制命令(重点三个)
    • IPC_RMID:标记删除共享内存,只有所有进程都 shmdt 脱离后,内核才真正释放,此时 buf 传 NULL
    • IPC_STAT:获取共享内存属性,存入 buf
    • IPC_SET:修改共享内存权限等属性

一般就用IPC_RMID

3、buf:shmid_ds 结构体指针,IPC_RMID 填 NULL

返回值

成功 0,失败 - 1

eg:if(shmctl(shmid,IPC_RMID,NULL)<0)

总结:
共享内存
a.key -- ftok
b.shmid -- shmget
c.映射 -- shmat
d.解除 -- shmdt
e.销毁 -- shmctl

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

JVM规范第 3 章:从 Java 源码到字节码

本教程基于 Oracle 官方《The Java Virtual Machine Specification》&#xff08;Java SE 26&#xff09;第 3 章《Compiling for the Java Virtual Machine》整理编写。这一章本身不是规范性内容&#xff0c;而是由 Oracle 的 javac 示例展示「Java 源码是怎么变成 JVM 指令的…

作者头像 李华
网站建设 2026/8/25 14:55:25

Agent Content Protocol: 一种基于 RFC 2046 的内容封装规范

Agent Content Protocol: 一种基于 RFC 2046 的内容封装规范 2026-08-22 Agent Content Protocol: 一种基于 RFC 2046 的内容封装规范 版本&#xff1a;0.5.0-draft1. 协议定位与核心宣言 1.1 定位 ACP 定义了一种可互操作的 Agent 消息内容信封。它规定了如何将一个 JSON 控制…

作者头像 李华
网站建设 2026/8/25 14:51:44

SkillGo,支持多用户与独立沙箱执行的 Skill 平台

一、为什么要做 SkillGo&#xff1f; 聚焦于解决&#xff1a; 创造一个私有化部署的社区&#xff0c;Skill 获得以后&#xff0c;在社区中怎样管理、怎样运行、怎样隔离&#xff0c;以及怎样将skill配置成可以接入业务系统的api。 这是 SkillGo 出现的原因。 GitHub&#xff1…

作者头像 李华
网站建设 2026/8/25 14:49:11

Python3.10自然语言处理项目:HuggingFace+镜像部署教程

.10自然语言处理项目&#xff1a;镜像部署教程想要迅速搭建一个归属于自身的 AI 开发环境, 然而又不愿被繁杂的依赖以及版本冲突弄得顾此失彼、疲惫不堪? 今日, 就在这里讲述一下怎样运用最为简单的方式, 在.10 环境里面, 借由一个预先配置好的镜像, 顺利实行部署生态, 进而开…

作者头像 李华