linux下的消息队列编程_第1页
linux下的消息队列编程_第2页
linux下的消息队列编程_第3页
linux下的消息队列编程_第4页
linux下的消息队列编程_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Linux 下的消息队列的使用SUNNY.MAN一、消息队列的基本概念消息队列(也叫做报文队列)是 Unix 系统 V 版本中进程间通信机制之一。消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。Linux 采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。消息队列是随内

2、核持续的并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构(structipc_idsmsg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids 中中找到访问入口。IPC 标识符:每一个 IPC 目标都有一个唯一的 IPC 标识符。这里所指的 IPC 目标是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 IPC 目标。IPC 关键字:想要获得唯一的标识符,则必须使用一个 IPC 关键字。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一

3、步。一般情况下,可以使用 ftok()函数为客户端和服务器端产生关键字值。#include#includekey_tftok(constchar*fname,intid)fname 就是你指定的文件名(已经存在的文件名),一般使用当前目录,如:key_tkey;key=ftok(.,1);这样就是将 fname 设为当前目录。id 是子序号在一般的 UNIX 实现中,是将文件的索引节点号取出, 前面加上子序号得到 key_t 的返回值。 如指定文件的索引节点号为65538,换算成 16 进制为 0 x010002,而你指定的 ID 值为 38,换算成 16 进制为 0 x26,则最后的 key

4、_t 返回值为 0 x26010002。查询文件索引节点号的方法是:ls-i 当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。如果要确保 key_t 值不变,要么确保 ftok 的文件不被删除,要么不用 ftok,指定一个固定的 key_t 值,比如:#defineIPCKEY0 x111charpath256;sprintf(path,%s/etc/config.ini,(char*)getenv(HOME);msgid=ftok(path,IPCKEY);也就是说其实 ftok 的作用就是根据你所指定的文件的索引点号生成一个

5、独一无二的KEY,并保持。不过在使用的过程中,一般都是直接指定一个固定的值,这样使用起来简单,但一定要确保和其它程序不冲突。二、使用消息队列查看一个系统中的消息可以用 ipcs-q 来查看,这可以看到 msgid 和权限以及当前有几条消息。当你在调试的过程中,由于程序没有正常结束,而你又想删除此消息时,请使用 ipcrm-qmsgid 命令。下面结合具体的实例代码详细说明一下使用的过程。Snd.c 文件#include#include#include#include#include#include#include#defineMAX_TEXT512#defineMSG_KEY335struct

6、my_msg_stlongmy_msg_type;/这个就是消息的类型,在接收的时候一定要指定这个/类型才会接收到相应的消息。charsome_textMAX_TEXT;intmain()inti=10;intrunning=1;structmy_msg_stsome_data;intmsgid;charbufferBUFSIZ;msgid=msgget(key_t)MSG_KEY,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);首先创建,如果不成功,就取得if(msgid=-1)printf(createfailegetimsgidn);msgid=msgget(ke

7、y_t)MSG_KEY,IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)fprintf(stderr,msggetfailedwitherror:%dn,errno);exit(EXIT_FAILURE);while(running)(printf(%dEntersometext:lessthan%dn,msgid,MAX_TEXT);fgets(buffer,BUFSIZ,stdin);some_data.my_msg_type=10;strcpy(some_data.some_text,buffer);if(msgsnd(msgid,(void*)&so

8、me_data,sizeof(some_data),0)=-1)(fprintf(stderr,msgsndfailedn);exit(EXIT_FAILURE);if(strncmp(buffer,end,3)=0)(running=0;exit(EXIT_SUCCESS);Rcv.c 文件#include#include#include#include#include#include#include#include#defineMAX_TEXT512#defineMSG_KEY335structmy_msg_st(longmy_msg_type;charsome_textMAX_TEXT;

9、intmain()(intrunning=1;intmsgid;structmy_msg_stsome_data;longintmsg_to_receive=10;msgid=msgget(key_t)MSG_KEY,IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)msgid=msgget(key_t)MSG_KEY,IPC_EXCL|S_IRUSR|S_IWUSR);if(msgid=-1)fprintf(stderr,msggetfailedwitherror:%dn,errno);exit(EXIT_FAILURE);printf(prep

10、arereceivemsg:%dn,msgid);while(running)/这里的 msg_to_receive 指定了接收消息的类型,如果类型不对,将取不到消息.IPC_NOWAIT 果消息队列里没有消息,则马上返回并设置 errno=ENOMSG 如果指定为 0 则将等待消息的到来。if(msgrcv(msgid,(void*)&some_data,sizeof(some_data),msg_to_receive,IPC_NOWAIT)=-1)if(ENOMSG=errno)printf(noMsgreceiven);continue;fprintf(stderr,msgrcv

11、failedwitherror:%dn,errno);exit(EXIT_FAILURE);printf(Youwrote:%s,some_data.some_text);if(strncmp(some_data.some_text,end,3)=0)running=0;if(msgctl(msgid,IPC_RMID,0)=-1)/使用这个库函数来移除消息队列。fprintf(stderr,msgctl(IPC_RMID)failedn);exit(EXIT_FAILURE);exit(EXIT_SUCCESS);.三、消息队列的相关参数1.查看系统中默认的消息队列的相关参数IpcsT 可以

12、查看当前消息队列的上限限制。Messages:Limitsmaxqueuessystemwide=162Gmaxsizeofmessage(bytes)=655362Gdefaultmaxsizeofqueue(bytes)=655362Gmsgmni 最大消息队列数msgmax 最大消息长度(字节数)msgmnb 消息队列中的最大字节数其实我们要关心的参数主要有三个,说得通俗点就是最多可以有多少个队列使用,每个队列里可以放多少消息,每个消息最多可以带多少内容。现在解释如下:系统中默认的消息列数是 16,最大可以达到 2G,系统中消息的个数和消息长度的总数,受队列最大尺寸限制。Msgmnb=m

13、sgmax*最大个数.其中消息队列的长度受结构使用。structmy_msg_stlongmy_msg_type;charsome_textMAX_TEXT;大家如果有兴趣,可以自己写个程序测试试下,简单的很就是无限制分配就可以了。修改消息队列的参数1 .永久修改root 用户下修改/etc/sysctl.conf 文件。2 .临时修改root 用户下 sysctl-wkernel.msgmnb=1048576/proc/sys/kernel/msgmax 单个消息的最大值/proc/sys/kernel/msgmnb 单个消息体的容量的最大值/proc/sys/kernel/msgmni 消

14、息体的数量缺省值为 16cat/proc/sys/kernel/shmmax可通过下面的方式进行设置echo819200/proc/sys/kernel/msgmaxecho1638400/proc/sys/kernel/msgmnbecho1600/proc/sys/kernel/msgmnicd/proc/sys/kernel;catmsgmax;catmsgmnb;catmsgmni;在程序中可以通过msgctl(msgid,IPC_STAT,&mymsq_ds);printf(%d,%d,%dn”,mymsq_ds.msg_qbytes,mymsq_ds.msg_qnum,mymsq_ds.msg_cbytes);来获得队列消息的总大小,已经有的消

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论