如何通过消息队列实现进程间通信

 我来答
亮视深物法纺2I
2018-09-29 · TA获得超过281个赞
知道小有建树答主
回答量:604
采纳率:47%
帮助的人:185万
展开全部
3. 1987版《聊斋》部分未拍摄和已删单元剧本情节简介 .聊斋吧[引用日期2014-01-18]
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友ded4135
高粉答主

2018-09-30 · 醉心答题,欢迎关注
知道大有可为答主
回答量:2.7万
采纳率:87%
帮助的人:1.2亿
展开全部
消息队列是消息的链接表,包括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 queue if(-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、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式