先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题

一 what

所谓共享内存通信,实际上就是在内核空间中有一个缓存数组,用于不同用户进程间实现通信。

共享内存是一种IPC通信对象,其他IPC通信对象还有消息队列以及信号灯。其处理思想和文件IO思想是一样的,也是open、write、read、close函数,只是函数形式方式了变化,如下所示:

二 why

简单来说,共享内存也是进程间通信的实现方法之一。

三 how

3.1 创建共享内存

函数原型 : int shmget(key_t key, int size, int shmflg)
函数参数 : key: IPC_PRIVATE 或 ftok的返回值IPC_PRIVATE返回的key值都是一样的,都是0size : 共享内存区大小shmflg : 同open函数的权限位,也可以用八进制表示法
返回值   : 成功,共享内存段标识符   ID   文件描述符; -1 出错

3.2 demo程序示例

3.2.1 使用IPC_PRIVAT宏创建

#include 

编译运行查看结果,我们发现key都是0

3.2.2 使用fotk函数创建key

ftok函数创建key值
函数原型 : char ftok(const char *path, char key)
参数 :path,文件路径和文件名key,一个字符
返回值 :正确返回一个key值,出错返回-1

#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"int main(int argc, char *argv[])
{int shmid;int key;key = ftok("./a.c", 'a');if (key < 0) {printf("create key failn");return -1;}printf("create key sucess key = 0x%Xn",key);shmid = shmget(key, 128, IPC_CREAT | 0777);if (shmid < 0) {printf("create shared memory failn");return -1;}printf("create shared memory sucess, shmid = %dn", shmid);system("ipcs -m");//system("ipcrm -m shmid");return 0;
}

编译运行

此时的key值就不在为0了,而是0x61110105。

3.2.3 为何需要ftok先创建key值呢?

这就类似于前面无名管道和有名管道,使用IPC_PRIVATE宏创建的共享内存就类似于无名管道,只能实现有亲缘关系的进程间通信。ftok函数创建了一个key值之后,就类似于有名管道,能够实现无亲缘关系的管道间通信。

3.2.4 用户空间如何操作共享内存

因为创建的共享内存仍然属于内核空间,用户空间如何操作这片共享内存呢?

shmat函数,将共享内存映射到用户空间,方便在用户空间操作
函数原型 :void *shmat(int shmid, const void *shmaddr, int shmflg)
参数 :shmid ID号shmaddr 映射到啊的地址, NULL为系统自动完成的映射shmflg SHM_RDONLY共享内存只读默认是0,可读可写
返回值:成功,映射后的结果;失败,返回NULL

示例代码

#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"int main(int argc, char *argv[])
{int shmid;int key;char *p;key = ftok("./a.c", 'b');if (key < 0) {printf("create key failn");return -1;}printf("create key sucess key = 0x%Xn",key);shmid = shmget(key, 128, IPC_CREAT | 0777);if (shmid < 0) {printf("create shared memory failn");return -1;}printf("create shared memory sucess, shmid = %dn", shmid);system("ipcs -m");p = (char *)shmat(shmid, NULL, 0);if (p == NULL) {printf("shmat failn");return -1;}printf("shmat sucessn");//write share memoryfgets(p, 128, stdin);//start read share memoryprintf("share memory data:%sn", p);//start read share memory againprintf("share memory data:%sn", p);//system("ipcrm -m shmid");return 0;
}

此时在console终端,通过键盘任意输入一串信息,console会打印出我们输入的信息,并且我们验证了连续2次读取同一个共享内存,发现内容都存在,这是和之前管道的区别,管道的内容读取完了之后,内容就不存在了。

3.2.5 删除用户空间的共享内存地址映射

shmdt
int shmdt(const void *shmaddr)
参数 ;shmat的返回值
返回值 : 成功0,出错-1

#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"
#include "string.h"int main(int argc, char *argv[])
{int shmid;int key;char *p;key = ftok("./a.c", 'b');if (key < 0) {printf("create key failn");return -1;}printf("create key sucess key = 0x%Xn",key);shmid = shmget(key, 128, IPC_CREAT | 0777);if (shmid < 0) {printf("create shared memory failn");return -1;}printf("create shared memory sucess, shmid = %dn", shmid);system("ipcs -m");p = (char *)shmat(shmid, NULL, 0);if (p == NULL) {printf("shmat failn");return -1;}printf("shmat sucessn");//write share memoryfgets(p, 128, stdin);//start read share memoryprintf("share memory data:%sn", p);//start read share memory againprintf("share memory data:%sn", p);//在用户空间删除共享内存的地址shmdt(p);memcpy(p, "abcd", 4);  //执行这个语句会出现segment faultreturn 0;
}

编译后执行,会出现segment fault,是正确的现象

3.2.6 删除内核空间的共享内存对象

shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
参数 ;shmid : 共享内存标识符cmd : IPC_START (获取对象属性)      --- 实现了命令 ipcs -mIPC_SET (设置对象属性)IPC_RMID (删除对象属性)       --- 实现了命令 ipcrm -mbuf : 指定IPC_START/IPC_SET时用以保存/设置属性
返回值 : 成功0,出错-1

#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"
#include "string.h"int main(int argc, char *argv[])
{int shmid;int key;char *p;key = ftok("./a.c", 'b');if (key < 0) {printf("create key failn");return -1;}printf("create key sucess key = 0x%Xn",key);shmid = shmget(key, 128, IPC_CREAT | 0777);if (shmid < 0) {printf("create shared memory failn");return -1;}printf("create shared memory sucess, shmid = %dn", shmid);system("ipcs -m");p = (char *)shmat(shmid, NULL, 0);if (p == NULL) {printf("shmat failn");return -1;}printf("shmat sucessn");//write share memoryfgets(p, 128, stdin);//start read share memoryprintf("share memory data:%sn", p);//start read share memory againprintf("share memory data:%sn", p);//在用户空间删除共享内存的地址shmdt(p);//memcpy(p, "abcd", 4);  //执行这个语句会出现segment faultshmctl(shmid, IPC_RMID, NULL); //会删除内核的共享内存对象system("ipcs -m");return 0;
}

linux 共享内存_linux进程间通信----IPC篇(一)----共享内存初识篇相关推荐

  1. Linux 进程间通讯(IPC)方式 ------- 共享内存

    Linux 进程间通讯(IPC)方式有以下几种: 1->管道(pipe)和有名管道(fifo). 2->消息队列 3->共享内存 4->信号量 5->信号(signal) ...

  2. java 共享内存ipc_进程间通信——IPC之共享内存

    共享内存是三个IPC机制中的一个.它允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在进行的进程之间传递数据的一种非常有效的方式. 大多数的共享内存的实现,都把由不同进程之间共享的内存安排为 ...

  3. Linux C 进程间的IPC通信 之 共享内存(二)

    1.父子进程(有亲缘关系)的IPC通信 int shmid;       shmid = shmget(IPC_PRIVATE, 128, IPC_CREAT | 0777); //创建共享内存,参数 ...

  4. linux java 共享内存_Linux进程间通信之共享内存

    一,共享内存 内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存. 映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点: ...

  5. linux 消息队列_Linux进程间通信第六讲 标准IPC之消息队列

    来源CSDN: CSDN-专业IT技术社区-登录​blog.csdn.net 一.概念和原理 消息队列是另一种标准IPC,当然也大概遵循大部分标准 消息队列,它是存放消息(数据)的队列,而队列是先进先 ...

  6. Linux C 进程间的IPC通信 之 共享内存(一)

    1.IPC(inter - process communication)通信 共享内存.消息队列.信号灯 2.库 <sys/shm.h> 2-1  创建共享内存 int shmget( k ...

  7. linux 修改 java 内存_Linux 和 Windows修改Java虚拟机内存大小

    因为内存溢出问题 1. Linux下直接修改%tomcat_home%/bin/catalina.sh文件 在注释下紧接一行也就是脚本正文开始之前 加上 Java_OPTS='-server -Xms ...

  8. linux java 进程内存_linux – 在java进程中消耗内存的是什么?

    我们正在尝试在中等负载下研究 java进程的内存使用情况. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 12663 test 20 0 ...

  9. 【Linux篇】第十二篇——进程间通信(管道+system V共享内存)

    进程间通信介绍 概念 目的 本质 分类 管道 什么是管道 匿名管道 匿名管道的原理 pipe函数 匿名管道使用步骤 管道读写规则 管道的特点 管道的大小 命名管道 命名管道的原理 使用命令创建命名管道 ...

最新文章

  1. java. xerces转xml_Xerces -C++遇到的xml编码转换问题
  2. 不用任何数学方法,如何计算圆面积
  3. python常用标准库有哪些-Python - 常用标准库
  4. 团队行为心理学读书笔记(2)招聘背后的心理学
  5. JEECG 3.7.1 非Maven版本源码下载,企业级JAVA快速开发平台
  6. BZOJ 2653 middle
  7. 百亿级日访问量的应用如何做缓存架构设计?
  8. 拓端tecdat|关联规则APRIORI挖掘豆瓣读书评论爬虫采集数据与可视化
  9. 方舟php服务器控制,方舟基本管理命令代码
  10. 使用Bochs写Hello world
  11. 美团 2021 届秋季校园招聘—小团的 AB 队(排序)
  12. 浏览器ocx控件安装 IE浏览器可用
  13. 微信营销如何做对o2o商业模式心灰意冷了吗?O2O到底要怎么做?
  14. 数据挖掘——决策树和K近邻
  15. rsync 服务方式连接
  16. Vant Weapp组件picker选择器初始默认选中
  17. 使用轻量级虚拟桌面基础架构 (VDI) 解决方案降低 IT 成本并保护数字知识产权
  18. 【产业互联网周报】销售易获腾讯1.2亿美元投资;国科恒泰完成11亿C轮融资;工信部、科技部推进大数据及人工智能...
  19. android实现气泡聊天
  20. Scrapy爬取和讯博客个人博客的信息并写人数据库

热门文章

  1. Android:获取存储卡路径的方式
  2. MTK:屏幕模板机制
  3. html onblur 函数执行了2次,JavaScript“onblur事件”调用函数失效 原因与解决方法
  4. 电源管理与驱动设计笔记
  5. schedule event mysql_mysql计划任务:event schedule
  6. opencv之解决对加载图片大小限制的问题
  7. python爬取学校题库_Python爬虫面试题
  8. Springboot邮箱接口(使用个人邮箱发送邮件)
  9. yum -y install php-mysql 版本冲突
  10. TOP100summit:【分享实录-QQ空间】10亿级直播背后的技术优化