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

下载本文档

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

文档简介

Linux下的消息队列的使用SUNNY.MAN一、消息队列的基本概念消息队列 (也叫做报文队列)是Unix系统V版本中进程间通信机制之一。消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。Linux采用消息队列的方式来实现消息传递。这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。消息队列是随内核持续的并和进程相关,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构 (struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中中找到访问入口。IPC标识符:每一个I P C目标都有一个唯一的I P C标识符。这里所指的I P C目标是指一个单独的消息队列、一个信号量集或者一个共享的内存段。系统内核使用此标识符在系统内核中指明 I P C目标。IPC 关键字:想要获得唯一的标识符,则必须使用一个 I P C关键字。客户端进程和服务器端进程必须双方都同意此关键字。这是建立一个客户机/服务器框架的第一步。一般情况下,可以使用ftok ( )函数为客户端和服务器端产生关键字值。#include #include key_t ftok( const char * fname, int id ) fname就是你指定的文件名(已经存在的文件名),一般使用当前目录,如: key_t key; key = ftok(., 1); 这样就是将fname设为当前目录。id是子序号在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。查询文件索引节点号的方法是: ls -i当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。 如果要确保key_t值不变,要么确保ftok的文件不被删除,要么不用ftok,指定一个固定的key_t值,比如: #define IPCKEY 0x111 char path256; sprintf( path, %s/etc/config.ini, (char*)getenv(HOME) ); msgid=ftok( path, IPCKEY );也就是说其实ftok的作用就是根据你所指定的文件的索引点号生成一个独一无二的KEY,并保持。不过在使用的过程中,一般都是直接指定一个固定的值,这样使用起来简单,但一定要确保和其它程序不冲突。二、使用消息队列查看一个系统中的消息可以用ipcs q来查看,这可以看到msgid和权限以及当前有几条消息。当你在调试的过程中,由于程序没有正常结束,而你又想删除此消息时,请使用ipcrm q msgid命令。下面结合具体的实例代码详细说明一下使用的过程。Snd.c文件#include #include #include #include #include #include #include #define MAX_TEXT 512#define MSG_KEY 335struct my_msg_st long my_msg_type;/这个就是消息的类型,在接收的时候一定要指定这个/类型才会接收到相应的消息。char some_textMAX_TEXT;int main()int i = 10;int running = 1;struct my_msg_st some_data;int msgid;char bufferBUFSIZ;msgid = msgget(key_t)MSG_KEY, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);/首先创建,如果不成功,就取得if(msgid=-1)printf(create faile get imsgidn);msgid=msgget(key_t)MSG_KEY,IPC_EXCL|S_IRUSR|S_IWUSR);if (msgid = -1) fprintf(stderr, msgget failed with error: %dn, errno);exit(EXIT_FAILURE);while(running) printf(%dEnter some text: less than %dn,msgid,MAX_TEXT);fgets(buffer, BUFSIZ, stdin);some_data.my_msg_type = 10;strcpy(some_data.some_text, buffer); if (msgsnd(msgid, (void *)&some_data, sizeof(some_data), 0) = -1) fprintf(stderr, msgsnd failedn); exit(EXIT_FAILURE); if(strncmp(buffer, end, 3) = 0) running = 0; exit(EXIT_SUCCESS);Rcv.c文件#include #include #include #include #include #include #include #include #define MAX_TEXT 512#define MSG_KEY 335struct my_msg_st long my_msg_type; char some_textMAX_TEXT; int main() int running = 1; int msgid; struct my_msg_st some_data; long int msg_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,msgget failed with error: %dn,errno); exit(EXIT_FAILURE); printf(prepare receive msg:%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(no Msg receiven);continue; fprintf(stderr, msgrcv failed with error: %dn, errno); exit(EXIT_FAILURE); printf(You wrote: %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.查看系统中默认的消息队列的相关参数Ipcs l可以查看当前消息队列的上限限制。- Messages: Limits -max queues system wide = 16 2Gmax size of message (bytes) = 65536 2Gdefault max size of queue (bytes) = 65536 2Gmsgmni 最大消息队列数 msgmax 最大消息长度(字节数)msgmnb 消息队列中的最大字节数其实我们要关心的参数主要有三个,说得通俗点就是最多可以有多少个队列使用,每个队列里可以放多少消息,每个消息最多可以带多少内容。现在解释如下:系统中默认的消息列数是16,最大可以达到2G,系统中消息的个数和消息长度的总数,受队列最大尺寸限制。Msgmnb= msgmax*最大个数.其中消息队列的长度受结构使用。struct my_msg_st long my_msg_type;char some_textMAX_TEXT;大家如果有兴趣,可以自己写个程序测试试下,简单的很就是无限制分配就可以了。修改消息队列的参数1.永久修改root用户下修改/etc/sysctl.conf 文件。2.临时修改root用户下sysctl -w kernel.msgmnb= 1048576/proc/sys/kernel/msgmax 单个消息的最大值/proc/sys/kernel/msgmnb 单个消息体的容量的最大值/proc/sys/kernel/msgmni 消息体的数量缺省值为16cat /proc/sys/kernel/shmmax可通过下面的方式进行设置echo 819200 /proc/sys/kernel/msgmaxecho 1638400 /proc/sys/kernel/msgmnb echo 1600 /proc/sys/kernel/msgmni cd /proc/sys/kernel ; cat msgmax;cat msgmnb; cat msgmni;在程序中可以通过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

提交评论