当前位置: 首页 > news >正文

网站提速微信邀请函制作软件

网站提速,微信邀请函制作软件,星巴克网站建设方案,南安梅山建设银行网站#x1f496;作者#xff1a;小树苗渴望变成参天大树#x1f388; #x1f389;作者宣言#xff1a;认真写好每一篇博客#x1f4a4; #x1f38a;作者gitee:gitee✨ #x1f49e;作者专栏#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法#x1f384; 如 果 你 … 作者小树苗渴望变成参天大树 作者宣言认真写好每一篇博客 作者gitee:gitee✨ 作者专栏C语言,数据结构初阶,Linux,C 动态规划算法 如 果 你 喜 欢 作 者 的 文 章 就 给 作 者 点 点 关 注 吧 文章目录 前言一、共享内存的原理二、直接代码2.1关于共享内存的四大接口2.2如何通信 三、扩展知识3.1 看看维护共享内存的结构体属性3.2 使用管道来实现同步互斥机制 四、总结 前言 今天我们来讲进程间通信的的另一个通信方式在第一篇讲解进程间通信的博客中博主就提到了SystemV标准的通信方式我们前面讲解的匿名管道和命名管道都是基于文件的但是共享内存不是基于文件的他的所有进程间通信最快的因为他的拷贝少共享内存的难点就在于他的接口多复杂因为SystemV标准下不止一个共享内存还有消息队列和信号量都需要类似的接口为了可以更好的复用接口函数接下来博主就来带大家学习共享内存。 讲解逻辑 直接原理讲解周边问题通过原理写一部分代码认识系统接口进行测试扩展代码去讲解 一、共享内存的原理 使用共享内存的目的是让进程间进行通信但是进程间通信的本质是让不同的进程看到同一份资源由共享内存这个名字可知这篇共享的资源是一块内存计算机中我们一般由的地址要不是虚拟地址要不是物理地址想形成可执行程序里面的地址我们目前不谈而虚拟地址是每个进程特有的所以我们猜测这块共享内存是物理内存的一块因为有了前面的两次通信方式的铺垫我们已经慢慢找到规律了那博主就以一份图给大家讲解一下共享内存的原理。 共享内存的原理很简单就上幅这个图片但是博主要讲一些周边问题 释放共享内存先去挂接再释放内存是相反的操作上面的操作都是进程直接做的吗不是是直接由os去做的原因涉及到物理内存了。那既然有os去操作的那么我们去创建使用或者释放都需要经过系统调用接口去让os帮助我们实现我们的不同进程通过共享内存进行通信另外的进程也需要通过共享内存来进行通信那么共享内存就不止一块由许多快那么这块共享内存都是需要管理起来的所以先描述再组织就对应我们上图的struct结构体。里面存放的是对共享内存的管理属性。 所以我们一会对共享内存的使用里面肯定会涉及到这个结构体里面的属性等会遇到了一个讲一个现在都讲解出来读者大概率不会理解。 二、直接代码 我们通过刚才的原理分析而且这些操作是需要通过系统调用接口的所以我们一步步的来介绍这些系统调用接口。 2.1关于共享内存的四大接口 一、申请共享内存接口 返回值用户层shmid此函数申请一块共享内存返回共享内存标识符可以先理解为和文件描述符唯一标志文件一样的道理。第二个参数是申请共享内存的大小。单位是字节第三个参数共享内存是为了给不同的进程使用那么使用这块内存之前只要由一个进程创建其他进程拿来用就行了那这个参数就是控制对共享内存的权限操作来看我们自己要掌握的权限 1IPC_CREAT:单独使用如果你申请的共享内存不存在就创建存在就获取返回 2IPC_CREAT | IPC_EXCL:如果你申请的共享内存不存在就创建,存在就报错这是保证了你创建的共享内存是最新的。IPC_EXCL不单独使用 3第三个就是传我们对应的权限如0666 上面的方式我们再讲解文件操作的时候就讲解过了write函数里面需要传这样的参数这些大写字母起始就是对应的宏。 第一个参数通过第三个参数我们怎么知道这个共享内存存不存在就好比你怎么保证让不同的进程看到同一份共享内存是一样的此时就有了我们的第一个参数接下来谈谈这个key。 1key是一个数字这个数字是多少不重要。关键在于他必须再内核中具有唯一性能够让不同的进程进程唯一标识 2第一个进程可以通过key来创建共享内存。第二个进程之后的进程只要拿着这个key就可以和第一个进程看到同一个共享内存了 3对于一个已经创好的共享内存key在哪大家还记得一个说管理共享内存的结构体吗key就在共享内存的描述对象里 4通过第一点想要key去唯一标识共享内存大家再回想一下命名管道是怎么唯一标识的是不是通过就和文件名所以这个key应该也类似于命名管道的标识方式。 5通过第二点我们通过key创建共享内存那么第一次创建的时候这个key怎么有 我们总结出四个结论和一个问题问题来到了这个key一开始时怎么产生的了按照第四点的结论我们来介绍一下这个函数ftok 第一个参数路径这个随便写 第二个参数这个是工程id我们可以随便去指定是一个数字 返回值内核层是一个共享内存标识符 我们上面的两个参数都是由用户自己去定义的所以可能会和系统中的key产生冲突这个函数是通过一个算法将两个参数进行运算的出来的这样的一个key,每次生成的结果都是不一样的不是你每次传的参数一样计算出来的结果就是一样的。这样为什么就可以做到key是唯一的呢我们的路径是唯一的而且第二个参数是我们自己传大概率也是唯一的这样就导致我们的key是唯一的而且一旦创建这个key就是这个共享内存所独有了如果再生成这个key只能获取不会再创建一个新的了 为什么key不由os自己创建呢我们自己创建还有可能造成key冲突的问题 1再谈谈key的时候的第二点我们知道这个我们通过创建共享内存是由一个进程去创建另一个进程去使用就可以如果这个key是os生成的创建好的共享内存那另一个没有关系的进程怎么获取这块共享内存因为共享内存不是唯一的所以os里面的key也不是唯一的所以没有办法给另一个进程让他获取啊有的人说传给另一个进程这样就出现蛋生鸡的问题另一个进程要key才能进行通信但是要key必须先通信如果共享内存的个数是唯一的那么可以让os自己生成大家自己理解一下 2这个key的获取可以说是用户的约定和哪个进程通信只有用户知道就是程序员知道两个进程使用ftok这个相同的方式就可以获取唯一的key因为这两个参数是唯一的 3有的人会说我们将系统自己生成的key通过管道传给另一个进程就可以了答案确实可以但是这样我们学习共享内存的成本就搞了还要先学习管道这样也不嫩恶搞保证共享内存是一个独立通信模块了 大家看到这里对于key的理解应该到位了但是有一个关键的点key vs shmid 这两个都是共享内存的标识符他两有一个不就行了key是内核中唯一标识的shmid只有再进程里唯一标识的我们操作共享共享内存的函数都是使用shmid。 通过上面的一系列分析我们来申请一块共享内存shmgetftok sham.hpp: #ifndef __COMM_HPP__ #define __COMM_HPP__#include iostream #include string #include cstdlib #include cstring #include sys/ipc.h #include sys/shm.h #include sys/types.h #include sys/types.h #include sys/stat.h#include log.hppusing namespace std;Log log;const int size 4096; const string pathname/home/xdh; const int proj_id 0x6666;key_t GetKey() {key_t k ftok(pathname.c_str(), proj_id);if(k 0){log(Fatal, ftok error: %s, strerror(errno));exit(1);}log(Info, ftok success, key is : 0x%x, k);return k; }int GetShareMemHelper(int flag) {key_t k GetKey();int shmid shmget(k, size, flag);if(shmid 0){log(Fatal, create share memory error: %s, strerror(errno));exit(2);}log(Info, create share memory success, shmid: %d, shmid);return shmid; }int CreateShm()//创建共享内存得到标识符shmid,进行了封装 {return GetShareMemHelper(IPC_CREAT | IPC_EXCL | 0666); } #endifprocessa.cc: #includesham.hpp //这是进程a,有这个进程创建共享内存 int main() {//申请共享内存int shmidCreateShm();sleep(5);return 0; }通过结果我们发现我们第一次运行程序的时候申请了一块共享内存获得了共享内存标识符但是第二次运行的时候显示就存在了我们使用ipcs -m 查看共享内存我们得出结论进程结束了我们的共享内存还是存在的共享内存的生命周期是随着内核的不是随着进程的通过原理图也不难理解这点没有关闭共享内存这也可能会造成内存泄漏类似于malloc。 这里面我们再来研究一个点我们申请4097个字节大小的空间看看效果 我们看到大小是4097在内核里面我们的os实际上会给我们的4096*2大小的空间但是我们只能使用4097这个大家要记住所以建议还是申请4096点整数倍折合人民币我们内存的页宽有关系大家先不用了解。 二、.挂接共享内存shmat函数 我们的共享内存申请好了我们就需要将其挂接到我们的地址空间上就是原理图上的第二步 第一个参数就是传刚才使用shmget函数的返回值即可是共享内存的唯一标识符第二个参数指定挂接到那个位置我们申请好了共享内存要挂接到我们进程的地址空间的共享群位置这么多位置总要找到一个位置的其实位置吧这样也方便我们页表进行映射所以需要制定我们在这里传空指针就好了意思让系统自己决定第三个参数是挂接的方式 我们在这里传0进去就好了 返回值我们就是把挂接到地址空间的那块位置的首地址返回出来让用户能拿到进行操作所以返回值是void需要强转和malloc类似,失败就返回(void)-1 我们来看代码实现 //将共享内存挂接到自己的地址空间char* shmaddr(char*)shmat(shmid,nullptr,0);if(*shmaddr0){log(Fatal,shmat flase:%s,strerror(errno));exit(3);}log(Info,shmat sucessful:%s,strerror(errno));sleep(3);我们来观察一下nattch这个属性他就是表示这块共享内存当前的挂接树没调用这个shmat函数之前为0调用之后为1而且当进程退出他的挂接数自然的就减少了1 三.去掉挂接关系shmdt 刚才是因为程序结束挂接数减少了但我们有时候程序没结束就像去挂接怎么做我们通过shmdt来去挂接来看文档 这个函数非常的简单就是传刚才挂接函数返回值就可以了我们直接来看使用效果: 我们分析我们3秒后创建共享内存5秒后挂接进程挂接数变成13秒后去挂接挂接数变成1在3秒后程序终止 int nshmdt(shmaddr);if(n0){log(Fatal,shmdt flase:%s,strerror(errno));}log(Info,shmdt sucessful:%s,strerror(errno));sleep(3);和我们预测的一样我们的挂接数不一定非得在程序结束才会减1 四.释放共享内存shmctl 我们想要将我们的共享概念内存释放掉使用shmctl 第一个参数共享内存唯一标识符 第三个参数是一个描述共享内存的状态和访问权限的数据结构也就是我们开头说的描述共享内存的结构图看到key在里面了吧对于这个参数我们可以传一个null因为不需要将状态获取到这是一个输出型参数和status一样。 第二个参数将要采取的动作就是对第三个参数实行什么样的操作有三个操作 我们关注的是最后一个删除共享内存 来看操作 int n1shmctl(shmid,IPC_RMID,nullptr);if(n10){log(Fatal,shmctl flase:%s,strerror(errno));}log(Info,shmctl sucessful:%s,strerror(errno));sleep(3);通过结果验证我们的讲解我们也可以通过ipcrm -m shmid来删除共享内存这个大家下去试试但是shmctl传进去的操作不一样功能就不一样如果传IPC_STAT,就可以查看属性。 我们将另一个进程也挂接到这个共享内存上吧因为申请和释放进程a帮助我们做了我们做的就是挂接和去挂接就可以了来看进程b的代码 先展示进程a的代码 #includesham.hpp //这是进程a,有这个进程创建共享内存 int main() {sleep(3);//申请共享内存int shmidCreateShm();sleep(5);//将共享内存挂接到自己的地址空间char* shmaddr(char*)shmat(shmid,nullptr,0);if(*shmaddr0){log(Fatal,shmat flase:%s,strerror(errno));exit(3);}log(Info,shmat sucessful:%s,strerror(errno));sleep(3);//去挂接int nshmdt(shmaddr);if(n0){log(Fatal,shmdt flase:%s,strerror(errno));}log(Info,shmdt sucessful:%s,strerror(errno));sleep(3);//释放共享内存int n1shmctl(shmid,IPC_RMID,nullptr);if(n10){log(Fatal,shmctl flase:%s,strerror(errno));}log(Info,shmctl sucessful:%s,strerror(errno));sleep(3);return 0; }进程b #include sham.hppint main() {sleep(3);int shmidGetShm();//这个函数在sham.hpp里面写就行了获取shmidsleep(5);//将共享内存挂接到自己的地址空间char* shmaddr(char*)shmat(shmid,nullptr,0);if(*shmaddr0){log(Fatal,shmat flase:%s,strerror(errno));exit(3);}log(Info,shmat sucessful:%s,strerror(errno));sleep(3);//去挂接int nshmdt(shmaddr);if(n0){log(Fatal,shmdt flase:%s,strerror(errno));}log(Info,shmdt sucessful:%s,strerror(errno));sleep(3);return 0; }我们也成功看到了挂接数变成了2上面讲解的一切都是让两个不同的进程之间看到同一份资源还没有开始通信 2.2如何通信 我们通过上面一系列的操作终于实现我们再原理图讲的内容了该说不说确实太复杂的但是这一系列的操作让他的通信显得非常的简单我们共享内存就是一块物理内存映射到我们进程的地址空间上我们程序通过这块地址空间上的地址就可以直接访问这块物理空间此时他就很想malloc申请空间然后去使用这块空间的方法很想我们一起来看操作让b写a读 a: while(true){couta sayshmaddrendl;sleep(1);}b: while(true){coutb enter;fgets(shmaddr,4096,stdin);sleep(1);}结论 我们我们两个进程对这块空间的操作是你搞你的我搞我的两者不受任何影响所以说明共享内存间是没有同步互斥机制的我们的共享内存是所有进程中通信速度最快因为拷贝少我们的共享内存的数据是用户自己去维护的所以这些看到和管道有不同的地方没有清空数据这是需要用户自己去决定的。 但是我们确实实现了两个进程间通信了有问题我们一会来解决。 三、扩展知识 3.1 看看维护共享内存的结构体属性 我们刚才的参数都是为了描述共享内存的所以维护共享概念给内存的属性有哪些呢刚才其实也大致看到了一些。 我们通过代码看看我们刚才提到一下属性 再a进程把通信代码改成下面的 int count0;struct shmid_ds shmds;while(true){sleep(1);if(count0){shmctl(shmid, IPC_STAT, shmds);cout shm size: shmds.shm_segsz endl;cout shm nattch: shmds.shm_nattch endl;printf(shm key: 0x%x\n, shmds.shm_perm.__key);cout shm mode: shmds.shm_perm.mode endl;}count;}3.2 使用管道来实现同步互斥机制 我们因为目前只学了System V的共享内存我们想要解决这个问题还可以使用信号量但是这个我们不做重点介绍等有机会我们在给大家讲解信号量是怎么解决共享内存的这个缺点我们今天就使用管道去解决这个问题吧因为是不相关的进程所以使用命名管道。 这个使用管道的方法其实和共享内存是一点关系没有之根据他会阻塞就不会执行下面的代码这样间接控制了。我们后面会简单介绍一下信号量是怎么解决这个问题的但是知识带大家了解一下。 四、总结 今天我们学习了共享内存学习成本和前面两个差不多前面是原理的铺垫大家不容易理解但是使用简单二共享内存有了前面的原理铺垫理解起来不难但是后面的使用接口对大家来说可能是一个难度大家下去好好把四大接口函数理解一下这对博主下一篇讲解消息队列以及信号量有很大帮助希望大家下来可以去自己实现博主这篇博客上面的内容我们下篇再见
http://www.zqtcl.cn/news/532860/

相关文章:

  • 电影发布网站模板天津网络维护公司
  • 如何用ae做模板下载网站平面设计线上培训机构
  • 地方宣传网站建设的必要性汕头企业网站建站模板
  • html网站源代码网站非法字符过滤
  • 江苏盐城建筑公司网站网络服务提供商是指什么
  • 汕头网站搜索优化视频广告制作
  • 靖边县建设局网站苏州企业网站建设公司价格
  • 沈阳微网站三好街 网站建设
  • 毕业答辩ppt模板免费下载网站网站域名使用怎么做分录
  • 建设购物网站要求网页制作与网站建设 pdf
  • 众创空间网站建设wordpress上传与安装包
  • 公司网站怎么做seo关键词排名优化销售
  • 企业网站建设如何去规划广西南宁网站建设哪家好
  • 类似头条的网站怎么做长丰县住房和城乡建设局网站
  • 密云青岛网站建设腾讯云cdn加速wordpress
  • windows 2008 iis添加网站长虹电视网站建设中
  • 金华网站建设公司哪家好沧州南皮网站建设公司
  • 站群网站程序软装设计师资格证
  • 邵阳经开区网站永康市住房建设局网站
  • 能够做代理的网站有哪些问题wordpress 建站视频
  • 凡科网做网站好吗厦门电商培训
  • 建立网站的目录结构时最好的做法是wordpress 恢复默认
  • 我需要把网站做东莞营销外包公司
  • 平台型网站制作住房和城乡建设网站 上海
  • 个人网站可以如果做淘宝客WordPress用quic
  • 建设网站要什么广告设计专业有什么可从事的工作
  • 网站开发上传视频教程济南网站建站模板
  • 深圳市城乡和建设局网站有哪些ui的设计网站
  • vs2010网站开发源码音乐网站设计怎么做
  • 长沙县政务网站网站色彩的应用