【LINUX C】消息队列

"消息队列"是在消息的传输过程中保存消息的容器。

1、Msgget

   作用:创建消息队列

   原型:int maggetkey_t keyint msgget);

   参数:

         Key 键值:IPC_PRIVATE设定一个私有的键值,也可由ftok函数来获得

         ftok原型如下:

         key_t ftok( char * fname, int id )

 

         fname就时你指定的文件名(该文件必须是存在而且可以访问的)id是子序号,虽然为int,但是只有8个比特被使用(0-255)

 

当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。

          Msgflag:权限

   返回值:成功就返回消息队列,失败: -1

   头文件:#include<sys/types.h>

           #include<sys/ipc.h>

           #include<sys/shm.h>

 

2、Msgsnd

   作用:写数据到消息队列

   原型:int msgsndint msgidconst void* msggpsize_t msgsizeint msgflg);

   参数:msggp:消息结构(消息类型+数据)

                 Struct msgbuf

                 {

                     Long msgtype;

                     Char mtex[1];

                 }

         Msgsize:正文消息的字节数

         MsgflagIPC_NOWAIT:写不进去消息,直接返回

                           0:一直等到能写进消息为止

  返回值:成功 0;失败 -1.

 

3、Msgrcv

   作用:从消息队列中发送数据

   原型:int msgrcv(int msgid, void *msgp, size_t msgsize,long int msgtype,int msgflg);

   参数:msgtyp : 0 接受消息队列的第一个消息

                 >0:接受消息队列第一个msgtyp消息

                 <0:  接受消息的第一个类型值

 

4、Msgctl

   作用:控制消息队列,可以删除消息队列

   原型:int msgctl(int msgid, int cmd, struct msgid_ds *buf);

   参数:msgid:消息队列ID

         CmdIPC_STAT: 读取消息队列的数据结构msgid_ds,存储在buf指定地址中

               IPC_SET:设置消息队列的权限

               IPC_RMID:删除消息队列

         Buf:消息队列的结构类型变量

  返回值: 成功 0 ; 出错 -1

 

键值相同,进的就是同一个队列


接收信息的程序源文件为msgreceive.c的源代码为:
[cpp]  view plain  copy
 print ?
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>  
  6. #include <sys/msg.h>  
  7.   
  8. struct msg_st  
  9. {  
  10.     long int msg_type;  
  11.     char text[BUFSIZ];  
  12. };  
  13.   
  14. int main()  
  15. {  
  16.     int running = 1;  
  17.     int msgid = -1;  
  18.     struct msg_st data;  
  19.     long int msgtype = 0; //注意1  
  20.   
  21.     //建立消息队列  
  22.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  23.     if(msgid == -1)  
  24.     {  
  25.         fprintf(stderr, "msgget failed with error: %d\n", errno);  
  26.         exit(EXIT_FAILURE);  
  27.     }  
  28.     //从队列中获取消息,直到遇到end消息为止  
  29.     while(running)  
  30.     {  
  31.         if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  
  32.         {  
  33.             fprintf(stderr, "msgrcv failed with errno: %d\n", errno);  
  34.             exit(EXIT_FAILURE);  
  35.         }  
  36.         printf("You wrote: %s\n",data.text);  
  37.         //遇到end结束  
  38.         if(strncmp(data.text, "end", 3) == 0)  
  39.             running = 0;  
  40.     }  
  41.     //删除消息队列  
  42.     if(msgctl(msgid, IPC_RMID, 0) == -1)  
  43.     {  
  44.         fprintf(stderr, "msgctl(IPC_RMID) failed\n");  
  45.         exit(EXIT_FAILURE);  
  46.     }  
  47.     exit(EXIT_SUCCESS);  
  48. }  
发送信息的程序的源文件msgsend.c的源代码为:
[cpp]  view plain  copy
 print ?
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <sys/msg.h>  
  6. #include <errno.h>  
  7.   
  8. #define MAX_TEXT 512  
  9. struct msg_st  
  10. {  
  11.     long int msg_type;  
  12.     char text[MAX_TEXT];  
  13. };  
  14.   
  15. int main()  
  16. {  
  17.     int running = 1;  
  18.     struct msg_st data;  
  19.     char buffer[BUFSIZ];  
  20.     int msgid = -1;  
  21.   
  22.     //建立消息队列  
  23.     msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  
  24.     if(msgid == -1)  
  25.     {  
  26.         fprintf(stderr, "msgget failed with error: %d\n", errno);  
  27.         exit(EXIT_FAILURE);  
  28.     }  
  29.   
  30.     //向消息队列中写消息,直到写入end  
  31.     while(running)  
  32.     {  
  33.         //输入数据  
  34.         printf("Enter some text: ");  
  35.         fgets(buffer, BUFSIZ, stdin);  
  36.         data.msg_type = 1;    //注意2  
  37.         strcpy(data.text, buffer);  
  38.         //向队列发送数据  
  39.         if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  
  40.         {  
  41.             fprintf(stderr, "msgsnd failed\n");  
  42.             exit(EXIT_FAILURE);  
  43.         }  
  44.         //输入end结束输入  
  45.         if(strncmp(buffer, "end", 3) == 0)  
  46.             running = 0;  
  47.         sleep(1);  
  48.     }  
  49.     exit(EXIT_SUCCESS);  
  50. }  

与命名管道相比,消息队列的优势在于:

1、消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。

2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法。

3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值