码迷,mamicode.com
首页 > 其他好文 > 详细

消息队列

时间:2016-02-06 14:16:59      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/ipc.h>
  4 #include<sys/types.h>
  5 #include<unistd.h>
  6 #include<sys/msg.h>
  7 
  8 void msg_stat(int msgid,struct msqid_ds msg_info)
  9 {
 10     int reval;
 11     sleep(1);
 12     reval=msgctl(msgid,IPC_STAT,&msg_info);
/*
msgctl函数
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
返回信息队列的属性
int msgctl(int msqid,int cmd ,struct msqid_ds *buf)
成功时返回0 失败返回-1

cmd命令有三个
IPC_STAT 获取消息队列信息,返回信息存储在buf指向的msqid_ds结构中
IPC_SET  设置消息队列属性,可以设置属性有
msg_perm.uid  msg_perm.gid  msg_perm.mode 

*/

 

 13     if(reval==-1)
 14     {
 15         printf("get msg info error\n");
 16         return;
 17     }
 18 
 19     printf("\n");
 20     printf("current number of bytes on queue is %ld\n",msg_info.msg_cbytes);
 21     printf("number of messages in queue is %hu\n",msg_info.msg_qnum);//注意数制转换,unsigned short 对应%hu(十进制) %ho(八进制) %hx(十六进制)
 22     printf("max number of bytes on queue is %hu\n",msg_info.msg_qbytes);
 23     printf("pid of last msgsnd is %d\n",msg_info.msg_lspid);
 24     printf("pid of last msgrcv is %d\n",msg_info.msg_lrpid);
25 26 printf("last msgsnd time is %s",ctime(&(msg_info.msg_stime))); 27 printf("last msgrcv time is %s",ctime(&(msg_info.msg_rtime))); 28 printf("last change time is %s",ctime(&(msg_info.msg_ctime))); 29 printf("msg uid is %d\n",msg_info.msg_perm.uid); 30 printf("msg gid is %d\n",msg_info.msg_perm.gid); 31 } 32 33 34 35 int main(void) 36 { 37 int gflags,sflags,rflags; 38 key_t key;
 1 /*
 2 key_t     //键值的类型
 3 用ftok函数获取一个键值
 4 函数原型  
 5 #include<sys/types.h>
 6 #include<sys/ipc.h>
 7 key_t ftok (char *pathname ,char proj);
 8 其中pathname是一个路径名,proj是子序号,只有8bit被使用
 9 
10 ftok获取键值的原理是将文件的索引节点号取出,前面加上子序号得到key_t的返回值
11 
12 */

 


39 int msgid; 40 int reval; 41
1 /*msgsbuf结构体
2 struct msgbuf    //发送数据缓冲区数据结构
3 {
4      long msgtype;//发送数据类型
5      char msgtext[size];//发送数据长度
6 }
7 */

 


    struct msgsbuf 42 { 43 long mtype; 44 char mtext[1]; 45 }msg_sbuf; 46 47 48 struct msgmbuf 49 { 50 long mtype; 51 char mtext[10]; 52 }msg_rbuf;//接收去缓存数据结构 53 54 struct msqid_ds msg_ginfo,msg_sinfo;
 1 /*
 2 msqid_ds 结构体
 3 struct msqid_ds
 4 {
 5       struct ipc_perm msg_perm; 
 6       struct msg *msg_first;//队列表头第一个信息
 7       struct msg *msg_last;//队列最后一个信息
 8       time_t msg_stime;//最终发送数据时间
 9       time_t msg_rtime;//最终接收数据时间
10       time_t msg_ctime;//最终更改时间
11       unsigned long msg_lcbytes;//32位回收再利用区
12       unsigned long msg_lqbytes;//同上
13       unsigned short msg_cbytes;//当前队列中的比特数
14       unsigned short msg_qnum;//队列中的消息数量
15       unsigned short msg_qbytes;//队列中的最大容纳比特数
16       pid_t msg_lspid;//最终发射的pid
17       pid_t msg_lrpid;//最新接收的pid
18 };
19 
20 
21 struct ipc_perm
22 {
23     key_t key;   \\该键值唯一对应一个消息队列
24     uid_t uid;    所有者的有效用户ID
25     gid_t gid;     所有者的有效组ID
26     uid_t cuid;   创建者的有效用户ID
27     gid_t cgid;    创建者的有效组ID
28     mode_t mode;   对象的访问权限
29     unsigned long seq;    对象序号
30 };
31 
32 
33 
34 time_t实际上是长整型,到未来的某一天,从一个时间点(一般是1970年1月1日0时0分0秒)到那时的秒数
35 */

 55     char *msgpath=".";//当前路径的键值
56 key=ftok(msgpath,a);//获取消息队列的键值 57 gflags=IPC_CREAT|IPC_EXCL;// 58 msgid=msgget(key,gflags|00666);
 1 /*
 2 msgget函数
 3 #include<sys/types.h>
 4 #include<sys/ipc.h>
 5 #include<sys/msg.h>
 6 int msgget(key_t key,int msgflg);
 7 
 8 
 9 key:消息队列关联的键。为IPC_PRIVATE时表示创建自己的消息队列     msgflg:消息队列的建立标志和访问权限。msgflg 的低位用来确定消息队列的访问权限。         
10 IPC_CREAT:如果 key不存在,创建         
11 IPC_EXCL:如果 key 存在,返回失败         
12 IPC_NOWAIT:如果需要等待,直接返回错误         
13 如果单独使用IPC_CREAT,则msgget()要么返回一个新创建的消息队列的标识符,要么返回具有相同关键字值的队列的标识符。
14 如果 IPC_EXCL和IPC_CREAT一起使用,则msgget()要么创建一个新的消息队列,要么如果队列已经存在则返回一个失败值-1。
15 举例:msgid=msgget(IPC_PRIVATE,IPC_CREAT|IPC_EXCL|00666); //创建消息队列
16 
  该函数返回与key所对应的标识符 17 */

 

 
59
if(msgid==-1)//消息队列创建失败,则返回-1 60 { 61 printf("msg creat error\n"); 62 return; 63 } 64 65 msg_stat(msgid,msg_ginfo);//msg_ginfo怎么没有赋值呢?原来它是用来接收的 66 sflags=IPC_NOWAIT; 67 msg_sbuf.mtype=10; 68 msg_sbuf.mtext[0]=a;
/*
msgsnd函数
函数原型
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgsnd (int msgid,const void *prt,size_t nbytes.int flags);
若成功返回0,出错返回-1

函数作用:向一个消息队列发送一个消息,该消息被添加到队列的末尾。

msgid是消息队列的应用标识符,参数prt指向要发送的缓冲区,nbytes是消息的数据长度,flags指出消息队列满时的处理方法
如果设置了IPC_NOWAIT,则立刻返回错误。


*/

 

 69     reval=msgsnd(msgid,&msg_sbuf,sizeof(msg_sbuf.mtext),sflags);
 70     if(reval==-1)
 71     {
 72         printf("message send error\n");
 73     }
 74     msg_stat(msgid,msg_ginfo);//第二次打印信息
 75     
 76     rflags=IPC_NOWAIT|MSG_NOERROR;
 1 /*
 2 msgrcv函数
 3 
 4 头文件:
 5      #include<sys/types.h>
 6      #include<sys/ipc.h>
 7      #include<sys/msg.h>
 8      int msgrcv(int msgid, void *ptr,size_t nytes,long type,int flags);
 9      若成功,返回消息的数据长度,若出错返回-1
10 
11 flags的取值
12      IPC_NOWAIT 如果没有满足条件的信息,立刻返回
13      IPC_EXCEPT  与type>0配合使用,返回队列中第一个不为type类型的消息
14      MSG_NOERROR 如果消息内容超出,则截断消息,截断部分消失
15 
16 type的取值:(要注意的是type的类型是long 如果用int传值的话,会出现值不匹配的现象17      type=0  接收消息队列中的第一条消息
18      type>0  接收消息队列中的等于type的第一条消息
19      type<0  接收消息队列中小于等于type绝对值中类型值最新的那一条消息

 

 77     reval=msgrcv(msgid,&msg_rbuf,4,10,rflags);//  
 78     if(reval==-1)
 79     {
 80         printf("read msg error\n");
 81     }    
 82     else
 83     {
 84         printf("read from msg queue %d types\n",reval);
 85     }
 86     
 87     msg_stat(msgid,msg_ginfo);//输出消息队列属性
 88     msg_sinfo.msg_perm.uid=8;
 89     msg_sinfo.msg_perm.gid=8;
 90     msg_sinfo.msg_qbytes=16388;
 91     reval=msgctl(msgid,IPC_SET,&msg_sinfo);
 92     if(reval==-1)
 93     {
 94         printf("msg set info error\n");
 95         return;
 96     }
 97     
 98     msg_stat(msgid,msg_ginfo);
 99     reval=msgctl(msgid,IPC_RMID,NULL);
100     if(reval==-1)
101     {
102         printf("unlink msg queue error\n");
103         return;
104     }
105     return 0;
106 }

 程序运行结果:

 1 gcc -o msg_app msg_app.c
 2 sudo ./msg_app
 3 
 4 current number of bytes on queue is 0
 5 number of messages in queue is 0
 6 max number of bytes on queue is 16384
 7 pid of last msgsnd is 0
 8 pid of last msgrcv is 0
 9 last msgsnd time is Thu Jan  1 08:00:00 1970
10 last msgrcv time is Thu Jan  1 08:00:00 1970
11 last change time is Sat Feb  6 11:23:36 2016
12 msg uid is 0
13 msg gid is 0
14 
15 current number of bytes on queue is 1
16 number of messages in queue is 1
17 max number of bytes on queue is 16384
18 pid of last msgsnd is 3983
19 pid of last msgrcv is 0
20 last msgsnd time is Sat Feb  6 11:23:37 2016
21 last msgrcv time is Thu Jan  1 08:00:00 1970
22 last change time is Sat Feb  6 11:23:36 2016
23 msg uid is 0
24 msg gid is 0
25 read from msg queue 1 types
26 
27 current number of bytes on queue is 0
28 number of messages in queue is 0
29 max number of bytes on queue is 16384
30 pid of last msgsnd is 3983
31 pid of last msgrcv is 3983
32 last msgsnd time is Sat Feb  6 11:23:37 2016
33 last msgrcv time is Sat Feb  6 11:23:38 2016
34 last change time is Sat Feb  6 11:23:36 2016
35 msg uid is 0
36 msg gid is 0
37 
38 current number of bytes on queue is 0
39 number of messages in queue is 0
40 max number of bytes on queue is 16388
41 pid of last msgsnd is 3983
42 pid of last msgrcv is 3983
43 last msgsnd time is Sat Feb  6 11:23:37 2016
44 last msgrcv time is Sat Feb  6 11:23:38 2016
45 last change time is Sat Feb  6 11:23:39 2016
46 msg uid is 8
47 msg gid is 8

 

消息队列

标签:

原文地址:http://www.cnblogs.com/wireless-dragon/p/5183961.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!