专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

进程间通信(IPC)系列Posix消息队列

  消息队列是LinuxIPC中很常用的一种通信方式,今天分析一下Posix消息队列,本文中所讲的消息队列均为Posix消息队列。什么是Posix消息队
  消息队列可以认为它是一个消息链表,有足够写权限的进程可以往队列中发送消息,有足够读权限的进程可以往队列中接收消息。
  每个消息都是一个记录,它由发送者赋予一个优先级。在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。这也就说明消息队列具有随内核的持续性,也就是说进程关闭后,消息队列依然存在,除非内核重新自举。
  Posix消息队列有如下特点:对Posix消息队列的读总是返回优先级最高最早的消息。当往空的消息队列中放置一个消息时,Posix消息队列允许产生一个信号或者启动一个接收线程。
  Posix消息队列中的每条消息通常具有以下属性:一个表示优先级的整数;消息的数据部分的长度;消息数据本身;
  消息队列的基本操作
  打开或创建一个posix消息队列操作接口
  mqdtmqopen(constcharname,intoflag,modetmode,structmqattrattr);
  Linkwithlrt。
  参数name为posixIPC名字,即将要被打开或创建的消息队列对象,为了便于移植,需要指定为name的格式。
  参数oflag必须要有ORDONLY(只读)、标志ORDWR(读写),OWRONLY(只写)之一,除此之外还可以指定OCREAT(没有该对象则创建)、OEXCL(如果OCREAT指定,但name不存在,就返回错误),ONONBLOCK(以非阻塞方式打开消息队列,在正常情况下mqreceive和mqsend函数会阻塞的地方,使用该标志打开的消息队列会返回EAGAIN错误)。
  当操作一个新队列时,使用OCREAT标识,此时后面两个参数需要被指定,参数mode为指定权限位,attr指定新创建队列的属性。
  关闭进程描述符操作接口intmqclose(mqdtmqdes);
  关闭之后告诉进程不在使用该描述符,但消息队列不会从系统中删除。
  系统中删除某个消息队列操作接口intmqunlink(constcharname);
  参数为mqopen()函数第一个参数,调用该接口后删除会马上发生,即使该队列的描述符引用计数仍然大于0。
  关于消息队列中设置和和获取消息队列属性接口mqdtmqgetattr(mqdtmqdes,structmqattrattr);mqdtmqsetattr(mqdtmqdes,structmqattrnewattr,structmqattroldattr);
  每个消息队列有四个属性,mqgetattr返回所有的这些属性,mqsetattr设置其中的某个属性
  消息队列的消息具体属性如下structmqattr{longmqflags;Flags:0orONONBLOCKlongmqmaxmsg;Max。ofmessagesonqueuelongmqmsgsize;Max。messagesize(bytes)longmqcurmsgs;ofmessagescurrentlyinqueue}
  指向mqattr的指针可以作为mqopen函数的第四个参数传递,从而在创建队列初就设置好每个消息的最大长度和允许存在的最大消息数量,另外两个成员被忽略。
  mqsetattr给所指定队列设置属性,但是只使用由attr指向的mqattr结构的mqflags成员,以设置或清除非阻塞标志,其他三个成员则被忽略(其中两个只能在创建队列时指定,还有一个及时获取)。当然,mqsetattr的最后一个参数用于接收之前的属性和当前状态
  向消息队列放置和取走消息的操作接口intmqsend(mqdtmqdes,constcharmsgptr,sizetmsglen,unsignedmsgprio);ssizetmqreceive(mqdtmqdes,charmsgptr,sizetmsglen,unsignedmsgprio);
  参数msgptr为指向消息的指针。
  msglen为消息长度,该值不能大于属性值中mqmsgsize的值。
  msgprio为优先级,消息在队列中将按照优先级大小顺序来排列消息。
  如果消息队列已满,mqsend()函数将阻塞,直到队列有可用空间再次允许放置消息或该调用被信号打断;如果ONONBLOCK被指定,mqsend()那么将不会阻塞,而是返回EAGAIN错误。
  如果队列空,mqreceive()函数将阻塞,直到消息队列中有新的消息;如果ONONBLOCK被指定,mqreceive()那么将不会阻塞,而是返回EAGAIN错误。消息队列的原理分析
  消息队列的初始化staticintinitinitmqueuefs(void){。。。注册消息队列文件系统errorregisterfilesystem(mqueuefstype);构建structvfsmount结构主要是获取文件系统的superblock对象与根目录的inode与dentry对象,并将这些对象加入到系统链表if(ISERR(mqueuemntkernmount(mqueuefstype))){。。。}queuescount0;spinlockinit(mqlock);return0;outfilesystem:outsysctl:returnerror;}initcall(initmqueuefs);
  消息队列文件系统初始化很简单,主要工作如下:注册文件系统,把mqueuefstype加入到filesystems链表中。构建structvfsmount结构,把获取的文件系统的superblock对象与根目录的inode与dentry对象,并将这些对象加入到系统链表中。
  mqopen接口分析asmlinkagelongsysmqopen(constcharuseruname,intoflag,modetmode,structmqattruseruattr){。。。获取一个未使用的文件描述符fdgetunusedfd();mutexlock(mqueuemntmntrootdinodeimutex);获取一个名字为name的dentry结构dentrylookuponelen(name,mqueuemntmntroot,strlen(name));mntget(mqueuemnt);若是新创建if(oflagOCREAT){if(dentrydinode){entryalreadyexistsauditinode(name,dentry);errorEEXIST;if(oflagOEXCL)gotoout;若已经存在,则直接打开filefilpdoopen(dentry,oflag);}else{创建一个file结构,把inode和dentry与之关联filpdocreate(mqueuemntmntroot,dentry,oflag,mode,uattr);}}else{否则,直接获取errorENOENT;if(!dentrydinode)gotoout;auditinode(name,dentry);filpdoopen(dentry,oflag);}if(ISERR(filp)){errorPTRERR(filp);gotooutputfd;}给描述符设置closeonexec标志setcloseonexec(fd,1);文件描述符与file进行关联fdinstall(fd,filp);gotooutupsem;。。。returnfd;}
  mqopen的操作很简单,操作如下:获取一个未使用的文件描述符fd;根据参数name获取一个dentry;根据oflag表示判断是否是新创建还是使用已存在的file,若新创建,则生成一个file结构,同时与fd、inode、dentry进行关联;否则打开一个已存在的file。
  mqsend接口分析
  当使用mqsend发送消息时,比如如下调用,mqsend(mqd,msg,msglen,msgprio)
  发送消息时,最终会调用如下函数mqtimedsend(mqd,msg,msglen,msgprio,NULL)
  asmlinkagelongsysmqtimedsend(mqdtmqdes,constcharuserumsgptr,sizetmsglen,unsignedintmsgprio,conststructtimespecuseruabstimeout){。。。获取file结构filpfget(mqdes);if(unlikely(!filp))gotoout;inodefilpfpath。dentrydinode;获取inode下的mqueueinodeinfoinfoMQUEUEI(inode);把用户传来的消息转换成内核消息链表,若用户消息长度大于PAGESIZE,则链表结构为msgmsgmsgmsgsegmsgmsgseg每个节点都已一个页大小,除了最后一个节点若用户消息大小小于PAGESIZE,链表只有一个节点msgmsgmsgptr指向链表头节点msgmsgmsgptrloadmsg(umsgptr,msglen);msgmsg中记录消息的总长度,和消息优先级msgptrmtsmsglen;msgptrmtypemsgprio;spinlock(infolock);若消息数量达到最大值if(infoattr。mqcurmsgsinfoattr。mqmaxmsg){若非阻塞,则返回if(filpfflagsONONBLOCK){spinunlock(infolock);retEAGAIN;若超时时间小于0,则返回超时时间}elseif(unlikely(timeout0)){spinunlock(infolock);rettimeout;}else{阻塞调用,则进程休眠,把wait加入到info中的SEND等待队列中wait。taskcurrent;wait。msg(void)msgptr;wait。stateSTATENONE;retwqsleep(info,SEND,timeout,wait);}}else{若info接收队列中有阻塞的进程,则把要发送的数据挂到阻塞的进程的消息节点上,然后唤醒阻塞的接收进程receiverwqgetfirstwaiter(info,RECV);if(receiver){pipelinedsend(info,msgptr,receiver);}else{把消息挂到消息队列上,并进行通知msginsert(msgptr,info);donotify(info);}inodeiatimeinodeimtimeinodeictimeCURRENTTIME;spinunlock(infolock);ret0;}returnret;}
  sysmqtimedsend功能如下:发送消息前先把用户消息转换成消息链表。若消息队列满了,则根据条件进行是否阻塞。消息队列未满,若接收队列中存在阻塞的接收进程,则把要发送的数据挂到阻塞的进程的消息节点上,然后唤醒阻塞的接收进程;否则把消息加到消息队列中。
  mqreceive接口分析
  当使用mqreceive接收消息时,比如如下调用,
  接收消息时,最终会调用如下函数mqtimedreceive(mqd,msg,msglen,msgprio,NULL)具体实现如下asmlinkagessizetsysmqtimedreceive(mqdtmqdes,charuserumsgptr,sizetmsglen,unsignedintuserumsgprio,conststructtimespecuseruabstimeout){。。。获取file结构filpfget(mqdes);inodefilpfpath。dentrydinode;获取inode下的mqueueinodeinfoinfoMQUEUEI(inode);auditinode(NULL,filpfpath。dentry);spinlock(infolock);消息队列当前没有消息if(infoattr。mqcurmsgs0){若非阻塞,则返回if(filpfflagsONONBLOCK){spinunlock(infolock);retEAGAIN;msgptrNULL;若超时时间小于0,则返回超时时间}elseif(unlikely(timeout0)){}else{阻塞调用,则进程休眠,把wait加入到info中的RECV等待队列中wait。taskcurrent;wait。stateSTATENONE;retwqsleep(info,RECV,timeout,wait);msgptrwait。msg;}}else{从消息队列的最高优先级中获取一个消息msgptrmsgget(info);inodeiatimeinodeimtimeinodeictimeCURRENTTIME;由于从消息队列中已经取出一个消息了,有剩余的空间,因此把等待SEND队列上的进程的消息挂到消息队里中,然后唤醒发送消息的进程pipelinedreceive(info);spinunlock(infolock);ret0;}if(ret0){retmsgptrmts;把消息拷贝到用户态if((umsgprioputuser(msgptrmtype,umsgprio))storemsg(umsgptr,msgptr,msgptrmts)){retEFAULT;}释放消息空间freemsg(msgptr);}outfput:fput(filp);out:returnret;}
  sysmqtimedreceive功能如下:获取消息前,先判断消息队列中是否有消息,若没有,则根据条件进行是否阻塞。若消息队列中有消息,则从消息队列的获取一个最高优先级的消息。唤醒因为消息队列满而阻塞的发送进程。把消息拷贝到用户缓冲区中。
  mqunlink接口分析asmlinkagelongsysmqunlink(constcharuseruname){。。。引用计数减1,删除目录项errvfsunlink(dentrydparentdinode,dentry);returnerr;}
  该函数作用很简单,就是减少引用计数,删除目录项。
  经过上述的分析,有关消息队列的内存结构可以总结如下:

国际美容教母郑明明殿堂级教母人物国际美容教母郑明明在美容界,是一个很知名的殿堂级教母人物。上个世纪七八十年代中期,她带着国际先进的护肤理念正式进军大陆,把适合东方女性肤质的先进护肤理念带向内地,推动内地美容行业更鞠婧祎银灰色挑染搭配红唇造型超靓!雪肤玉貌又美出新高10月20日,鞠婧祎放出一组杂志拍摄花絮,魅力十足。鞠婧祎身穿黑色衣裤,她俏脸清丽,秀眸明亮,浓郁眼妆搭配红唇,银灰色挑染在浓密黑发中别致抓眼,她站在沙发前面优雅大方,美得让人窒息伊丽莎白泰勒与她的珠宝们(上)翡翠钻石耳吊坠一对翡翠和钻石耳吊坠,作者宝格丽,1960年,理查德伯顿的礼物1962年,她在阿拉伯劳伦斯的巴黎首映式上穿着它们1976年,她在华盛顿迎接伊丽莎白女王它们是她在V。I秋天的美超温柔请先说你好可爱其实所有纠结做选择的人,心里早就有答案的,咨询只是想得到内心所倾向的选择。最终的所谓命运,还是需要自己一步步走出来。你可爱有趣漂亮,如精灵被世俗所掩藏,你不是没人爱,我要为祥林嫂正名提到祥林嫂,人们总会联想到她喋喋不休地诉说自己的苦难,听得所有人都厌烦了。久而久之,祥林嫂成为爱抱怨的代名词,很多人也会在劝说别人的时候说不要整天跟祥林嫂一样抱怨这个抱怨那个。如果格林赛间和詹姆斯谈笑做的对吗?比赛进入第三节的时候,中间的一次插曲,詹姆斯听到有人喊格林,扭头跑过去,和格林寒暄了几句,俩人有说有笑,好不快活!反观勇士替补席上,哎呦我去,你瞅瞅一个个的,库里那表情,好像就是在菲利普柯蒂纽如果你希望在职业上取得成功,就必须学习中文老外讲故事海外员工看中国(43)英文名FilipeCoutinho中文名菲利普柯蒂纽国籍巴西职业中国宝武宝钢股份宝钢美洲有限公司巴西代表处销售经理金句如果你想有所成就,就必须学习中文,因为未来属于中国42岁的巴西2019届新秀合同即将到期,除了锡安莫兰特,还有哪些球员完成续约在2019年进入联盟的球员迎来了自己在新秀合同的最后一年,在这一年里,他们要更加专注在球场之上,因为这将关乎到他们的下一份合同。锡安和莫兰特是这一届球员中的绝对强者,他们已经完成了强者不言,善者不评,智者不辩说话是银,沉默是金。海明威说我们用三年学说话,却用一生学闭嘴。随着年岁渐长,你会悟到生活不需要夸夸其谈,妙语连珠,而是在沉静中自守,不因嘴巴招惹是非。强者不言,善者不评,智者不辩。如果可以(原创作者刘云)如果可以(原创作者刘云)如果翅膀还坚强羽翼还丰满一定将她笔直竖起一定将她竭力绽放绽放出江南的杏花烟雨绽放出北国的风光旖旎让世人惊艳她的缤纷多彩让世界惊叹她的绚烂神奇。在筋疲力尽时颔厦门大学王传超深度解读,诺奖得主帕博的主要贡献以及成功的关键导读我们是怎么进化来的,是什么让我们与众不同?这些问题自古以来一直吸引着人类学家去探索。2022年诺贝尔生理或医学奖授予了德国马普进化人类学研究所斯万特帕博(SvantePbo),
未来将会成为主流的4大行业,群雄并起,建议大家把握机遇3年疫情剥夺了我们的时间自由财富等等,如今全面开放已在践行,许多行业都已完全复工,恢复了往日的生机。彼此同时大家也开始关注未来将会有哪些行业成为主流,想要收集一手资料。翻来覆去看,景美还免费,这处宝藏公园不来打卡就亏了新春逛杨浦新年逛杨浦带你来打卡在阿拉杨浦有个不用花一分钱就能享受到的上海市区面积最大以森林为主要特色的公园Ta就是共青森林公园今天就让我们一起来逛逛吧共青森林公园园区分为南北两园,风格各有不山西太原古街聚人气夜经济不断升温央视网消息随着天气转暖,夜经济也开始升温。山西太原的钟楼街是当地历史悠久的繁华街市,这里不仅是市民游客拍照打卡的好去处,还为周边商户带来更多商机。夜幕降临,记者在山西太原钟楼街看到今天被好客山东,好品山东刷屏了!今天被好客山东,好品山东刷屏了!今天一大早,一位在北京工作的大学师姐,就给我刷了一组照片。这是人民日报又一次整版推介好客山东好品山东。看到这些图片,真是油然而生的自豪感。作为生活在西湖边最美人墙有了新成员亚运吉祥物也来当志愿者随着天气的回暖,杭州的人气也越来越旺,周末的湖滨步行街游人如织,最美人墙也如期而至。在杭州亚运会倒计时200天即将来临之际,35学雷锋纪念日这一天,这支志愿服务队伍新增了三位特殊的上半年换机别盲目!数码老司机带你盘点三款重磅新机产品力拉满正值开春之际,近期各大手机厂商相继将新机提上发布日程,根据预热信息和爆料来看,这些新机可谓黑科技频出,对于广大消费者而言无疑有着巨大的吸引力,又到了更换手机的黄金时机。那么,如何才地球是平的相信平地论的人为什么会这么坚信不移?地球是平的这个观点在科学界已经被证明是错的,但是仍有一些人坚信着这个说法。那么,为什么会有人如此坚信这个观点呢?支持地平说的人们认为,万有引力其实是人类的错觉,根本不存在所谓的引力OPPOFindX6最新确认屏幕超越苹果14Pro,3月21日发布作为OPPO旗下的高端旗舰代表作,FindX系列手机受到了多方关注,让不少用户印象十分深刻的是,FindX5系列采用了独一无二的造型设计,结合一体化陶瓷机身设计,在颜值和手感上都有入手宋PLUS有段时间了,4500公里后,车主说了小缺点!我认为自主品牌不差!国产新能源,我只认比亚迪这个品牌!比亚迪作为全球第二大电池供应商!三电系统有着先进的技术!之前关注比亚迪DM技术,主要是追求性能,提速快!自从DMl技术和刀片电居然好多人不知道京东夺宝岛可以买京东自营二手?本内容来源于什么值得买APP,观点仅代表作者本人作者了她的亲爸爸发了一个关于夺宝岛的笔记浏览人数很多呀,那我就为大家详细介绍一下京东的夺宝岛吧。什么是夺宝岛?夺宝多又叫拍拍,是京东湖南新田樱花烂漫乐享春光(组图)樱花树下享春光。赏花拍照。漫步樱花林。奔跑在樱花林中。樱花树下小顽童。在樱花林中赏花休憩。乐游樱花林。乐享美好春光。红网时刻新闻3月6日讯(通讯员钟伟锋)3月5日,天气晴好,湖南省
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网