linux SysV IPC shm共享内存实现-程序员宅基地

技术标签: k-ipc  ipc  

共享内存可以使多个进程共享某段内存,由于不需要进程间数据复制,所以是速度最快的IPC。
多个进程访问共享内存时需要同步机制,如进程A往共享内存中写数据时,进程B不能使用共享内存;通常采用信号量同步多进程访问共享内存。

共享内存实现主要有以下几点:
1.分配物理内存
2.将物理内存映射到进程的地址空间;通过修改进程的页表,可以虚拟地址直接访问物理内存
3.进程不再使用共享内存时,取消物理内存在进程地址空间的映射

tmpfs文件系统将所有文件存储在内存(而非硬盘等介质)中;tmpfs将所有的东西存放在内核缓存中,可以根据文件系统中所容纳的文件自动增长和收缩,也可以将不使用的页swap出去。
linux共享内存的实现基于tmpfs文件系统及mmap文件映射;通过在tmpfs中创建文件来获取物理内存,将文件映射到进程地址空间后可以使用虚拟地址访问共享内存。


I.数据结构
include/linux/shm.h

 86 struct shmid_kernel /* private to the kernel */
 87 {
 88         struct kern_ipc_perm    shm_perm;       /* operation perms */
 89         struct file *           shm_file;       /* tmpfs file */
 90         unsigned long           shm_nattch;     /* no. of current attaches */
 91         unsigned long           shm_segsz;      /* size of segment (bytes) */
 92         time_t                  shm_atim;       /* last attach time */
 93         time_t                  shm_dtim;       /* last detach time */
 94         time_t                  shm_ctim;       /* last change time */
 95         pid_t                   shm_cprid;      /* pid of creator */
 96         pid_t                   shm_lprid;      /* pid of last operator */
 97         struct user_struct      *mlock_user;
 98 };

shmid_kernel用于存放共享内存信息
注:
  shm_file存放tmpfs中创建的内存文件,用于分配物理内存;用tmpfs的文件映射功能直接将共享内存映射到进程地址空间

 

ipc/shm.c

  48 struct shm_file_data {
  49         int id;
  50         struct ipc_namespace *ns;
  51         struct file *file;
  52         const struct vm_operations_struct *vm_ops;
  53 };

shm_file_data主要用于保存文件(tmpfs文件)内存映射的虚拟内存操作集vm_ops,进而扩展vm_ops,使某进程已经调用IPC_RMID,其它所有进程detach后能正常释放共享内存IPC资源
注:
  共享内存主要涉及两种文件,tmpfs文件与shm文件;一个共享内存对应一个tmpfs文件,有多少个进程attach到共享内存就有多少个shm文件。
  为什么要在tmpfs文件上层再加shm文件呢?直接将tmpfs文件映射到多个进程地址空间不就能实现内存共享了吗?
  的确,可以将tmpfs文件映射到多个进程地址空间,并能实现内存共享。但是有一种特殊情况,当多个进程attach到共享内存,此时某个进程删除共享内存,为了保证其他进程能继续正常使用共享内存,则暂不能删除共享内存的IPC资源;而所有的进程detach后,tmpfs文件munmap又不能删除IPC资源。
  所以在tmpfs文件上层添加shm文件,用于扩展tmpfs文件映射的vm_ops,来实现所有进程detach后删除共享内存的IPC资源。
  详细代码参见:do_shm_rmid、shm_close
 


II.共享内存创建

 326 /**
 327  * newseg - Create a new shared memory segment
 328  * @ns: namespace
 329  * @params: ptr to the structure that contains key, size and shmflg
 330  *
 331  * Called with shm_ids.rw_mutex held as a writer.
 332  */
 333 
 334 static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 335 {
 336         key_t key = params->key;
 337         int shmflg = params->flg;
 338         size_t size = params->u.size;
 339         int error;
 340         struct shmid_kernel *shp;
 341         int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
 342         struct file * file;
 343         char name[13];
 344         int id;
 345         int acctflag = 0;
 346 
 347         if (size < SHMMIN || size > ns->shm_ctlmax)
 348                 return -EINVAL;
 349 
 350         if (ns->shm_tot + numpages > ns->shm_ctlall)
 351                 return -ENOSPC;
 352 
 353         shp = ipc_rcu_alloc(sizeof(*shp));
 354         if (!shp)
 355                 return -ENOMEM;
 356 
 357         shp->shm_perm.key = key;
 358         shp->shm_perm.mode = (shmflg & S_IRWXUGO);
 359         shp->mlock_user = NULL;
 360 
 361         shp->shm_perm.security = NULL;
 362         error = security_shm_alloc(shp);
 363         if (error) {
 364                 ipc_rcu_putref(shp);
 365                 return error;
 366         }
 367 
 368         sprintf (name, "SYSV%08x", key);
 369         if (shmflg & SHM_HUGETLB) {
 370                 /* hugetlb_file_setup applies strict accounting */
 371                 if (shmflg & SHM_NORESERVE)
 372                         acctflag = VM_NORESERVE;
 373                 file = hugetlb_file_setup(name, size, acctflag,
 374                                         &shp->mlock_user, HUGETLB_SHMFS_INODE);
 375         } else {
 376                 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Morphad/article/details/9148437

智能推荐

基于Python通过WMI方式监控Windows服务-程序员宅基地

文章浏览阅读2.3k次。 因为在前期需求的讨论中,团队对返回的数据格式有一定要求,所以以下代码中会出现列表中嵌套字典或者多层嵌套的形式,废话不多说,直接上代码: 一:获取CPU相关信息(几核,每个核的占用率) cpu_list = [] cpu_dic = {} cpurate = self.queryByWql("\"select LoadPercentage,NumberOfCores ...

typeorm mysql2_从零搭建项目(10) --- 后端: 使用TypeORM和MySQL-程序员宅基地

文章浏览阅读117次。我的博客地址正式地址测试地址前端源码后端源码文章目录项目及其技术栈介绍前端: 项目初始化前端: 使用Sass和Antd前端: 开发体验优化前端: 搭建路由和状态管理前端: 支持Axios前端: 打包与环境变量设置前端: 团队代码规范后端: 项目初始化和使用Koa相关后端: 使用TypeORM和MySQL部署: 使用nginx部署前端项目部署: 后端部署部署: 使用jenkins自动化部署前言本章将..._@types/mysql2

vuex(store)利用插件持久化到本地储存的方法_store持久化-程序员宅基地

文章浏览阅读2.1k次,点赞2次,收藏3次。使用store管理数据 (vuex)—什么是vuex?基本使用/实现过程图/什么时候使用/优势在如上使用中会有一个弊端就是每次刷新数据对象会重新加载为空,这时候可以考虑使用本地储存持久化。监听vuex变化,如果数据改变就存放到本地储存如果页面刷新就从本地储存中重新取出数据store与本地储存的区别是本地储存由于不属于vue的一部分,没有实时更新的功能(需要刷新才重新渲染)nuxtjs中store不能直接使用浏览器的lcoalStorage方法,而且自己写数据同步功能比较麻烦,所以可以需.._store持久化

【Pi工具】开启树莓派的SPI及IIC_unable to open i2c device: no such file or directo-程序员宅基地

文章浏览阅读1.6w次,点赞2次,收藏14次。前言树莓派默认是将SPI和I2C功能关闭的,如果你编写SPI的程序,但是SPI模块没打开,可能会出现如下错误:ERROR: could not insert 'spi_bcm2708': No such device下面我们就针对如何开启SPI功能做下简单的说明,当然开启其他功能也是完全一样的。在终端输入sudo raspi-config命令,然后按照下图顺序依次操作即_unable to open i2c device: no such file or directory

【区块链2.0实战学习笔记】————8、Solidity开发以太坊游戏_solidity链游pve开发-程序员宅基地

文章浏览阅读813次。8.1 以太坊游戏的特点8.2 以太坊游戏开发准备8.3 以太坊游戏Influence代码框架8.4 以太坊游戏Influence源代码解读8.4.1 游戏界面8.4.2 库文件lib8.4.3 游戏主功能:小行星拍卖8.4.4..._solidity链游pve开发

python中文件读写--open函数详解_python open 读-程序员宅基地

文章浏览阅读7.2k次,点赞6次,收藏39次。python中open函数详解在python中文件的读取分为三步走:读:打开文件 -> 读文件 -> 关闭文件(有点像把大象放进冰箱需要几步?的问题)1、open函数open函数主要运用到两个参数,文件名和mode,文件名是添加该文件对象的变量,mode是告诉编译器和开发者文件通过怎样的方式进行使用。因此在Python中打开文件的代码如下:file_object = open('filename','mode')..._python open 读

随便推点

css:图标与文字对齐的两种方法-程序员宅基地

文章浏览阅读429次。(好久没写博客了,这几个月的积累比较零碎,记在本子上,现在开始整理归类)在平时写页面的过程中,常遇到要把小图标与文字对齐的情况。比如: 总结了两种方法,代码量都比较少。第一种    对img设置..._小程序 css图标与多行文字对齐

线性代数向量乘法_标量乘法属性1 | 使用Python的线性代数-程序员宅基地

文章浏览阅读380次。线性代数向量乘法Prerequisite: Linear Algebra | Defining a Vector 先决条件: 线性代数| 定义向量 Linear algebra is the branch of mathematics concerning linear equations by using vector spaces and through matrices. In othe..._向量标量乘法

Android屏幕适配-程序员宅基地

文章浏览阅读91次。屏幕适配非常好用的Android屏幕适配:https://www.jianshu.com/p/1302ad5a4b04今日头条屏幕适配方案终极版:http://blog.itpub.net/31077337/viewspace-2212649/秦子帅:Android刘海屏适配方案...

ELK生态:Logstash增量读取csv文件数据,导入到Elasticsearch_使用logstash导出es数据到csv-程序员宅基地

文章浏览阅读5k次。简介ELK生态之Logstash导入数据到Elasticsearch; 数据源:csv格式文件; Elasticsearch和Logstash版本:5.6.1; 前提环境:Elasticsearch单机或集群;Logstash客户端;实践csv文件内容:"sixmonth","23","男","1998/6/3 18:31:46""xiaoming","23","男","19..._使用logstash导出es数据到csv

eclipse链接git(SSH免密码链接)_eclipse git ssh-程序员宅基地

文章浏览阅读6.6k次。eclipse 使用ssh方式连接git_eclipse git ssh

HTML代码页面无法跳转为什么,html超链接不跳转 html为什么超链接不跳转页面-程序员宅基地

文章浏览阅读1.2w次。html里面代码加上超链接不跳转网页html为什么点击超链接不跳转?代码如下:点击链接 点击后你的链接是不是在框架里面 如果是要加上 target="_top"如何设置在html中保留超链接格式但不实现跳转html为什么超链接不跳转页面检查一下html超链接是否书写正确。html 超链接如何设置点击跳转到根目录或其他目录超链接跳转到其他的目录或者根目录一般是使用相对路径或者绝对路径的进行跳转。 工..._htm为什么value无法跳转