Linux进程间通信——消息队列应用实例

来源:互联网 发布:知乎年薪百万是什么梗 编辑:程序博客网 时间:2024/05/16 05:11

    消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。下面是两个测试模块

接收模块

msgreceive.c 的代码如下

/*============================================================================= #     FileName: msgreceive.c#         Desc: receice message from message queue #       Author: Licaibiao #      Version:  #   LastChange: 2017-01-20#      History: =============================================================================*/#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/msg.h>struct msg_st{long int msg_type;char text[128];};int main(){int running = 1;int msgid = -1;int len = 0;long int msgtype = 5; struct msg_st data;msgid = msgget((key_t)1234, 0666 | IPC_CREAT);if(-1 == msgid ){fprintf(stderr, "msgget failed with error: %d\n", errno);exit(EXIT_FAILURE);}while(running){memset(&data.text, 0, 128);len = msgrcv(msgid, (void*)&data, 128, msgtype, 0);if(-1 == len){fprintf(stderr, "msgrcv failed with errno: %d\n", errno);exit(EXIT_FAILURE);}printf("You wrote: %s\n",data.text);if(0 == strncmp(data.text, "end", 3))running = 0;}//remove message queueif(-1 == msgctl(msgid, IPC_RMID, 0)){fprintf(stderr, "msgctl(IPC_RMID) failed\n");exit(EXIT_FAILURE);}exit(EXIT_SUCCESS);}



发送模块

/*=============================================================================#     FileName: msgsend.c#         Desc: send data to message queue#       Author: Licaibiao#      Version: #   LastChange: 2017-01-20 #      History:=============================================================================*/#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/msg.h>#include <errno.h>#define MAX_TEXT 512struct msg_st{long int msg_type;char text[MAX_TEXT];};int main(){int running = 1;struct msg_st data;char buffer[BUFSIZ];int msgid = -1;int len;msgid = msgget((key_t)1234, 0666 | IPC_CREAT);if(msgid == -1){fprintf(stderr, "msgget failed with error: %d\n", errno);exit(EXIT_FAILURE);}while(running){printf("Enter data : ");fgets(buffer, BUFSIZ, stdin);data.msg_type = 5;    strcpy(data.text, buffer);    len = strlen(data.text);if(msgsnd(msgid, (void*)&data, len-1, 0) == -1){fprintf(stderr, "msgsnd failed\n");exit(EXIT_FAILURE);}if(strncmp(buffer, "end", 3) == 0)running = 0;usleep(100000);}exit(EXIT_SUCCESS);}

编译执行结果如下:

root@ubuntu:/home/test/msg_test# gcc msgsend.c  -o send root@ubuntu:/home/test/msg_test# gcc msgreceive.c -o recv root@ubuntu:/home/test/msg_test# ./recv &[1] 106594root@ubuntu:/home/ysj000/quanzhiSDK/F25_test/test/msg_test# ./send Enter data : helloYou wrote: helloEnter data : testYou wrote: testEnter data : hello worldYou wrote: hello worldEnter data : endYou wrote: end[1]+  Done                    ./recvroot@ubuntu:/home/test/msg_test# 
    这里需要注意,在接收端消息队列类型中的msg_type,如果设置为0,则表示接收所有的消息。如果非零,则只接收与发送端类型一样的消息。比如接收端设置为3,那么接收端只接收发送端msg_type为3进程发送过来的消息。

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

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

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

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



0 0
原创粉丝点击