Linux进程间通信之消息队列
2016-10-06 16:22
337 查看
本文依据以下思路展开,首先从宏观上阐述消息队列的机制,然后以具体代码为例进一步阐述该机制,最后试着畅想一下该通信机制潜在的应用。
消息队列是在两个不相关进程间传递数据的一种简单、高效方式,她独立于发送进程、接受进程而存在。
图1消息队列通信机制示意图
首先从宏观的角度了解一下消息队列的工作机制。因为消息队列独立于进程而存在,为了区别不同的消息队列,需要以key值标记消息队列,这样两个不相关进程可以通过事先约定的key值进行消息收发。例如进程A向key消息队列发送消息,进程B从Key消息队列读取消息。在这一过程中主要涉及到四个函数:
下面结合代码实例,对上述过程进行分析(具体分析见代码注释)
以下是在控制台模拟的结果:
$./msg2
Entersometext:hello
Entersometext:Howareyoutoday?
Entersometext:end
$./msg1
Youwrote:hello
Youwrote:Howareyoutoday?
Youwrote:end
$
消息队列潜在应用
图2消息队列在守护进程中的应用
如图2所示,假如有三个图形界面程序,他们分别对应进程1、进程2、进程3。这三个应用程序都需要鼠标、键盘操作,如果在每个进程都加入捕获鼠标、键盘操作的代码,那么一共需要三份这样的代码,有点浪费资源(内存空间)。如果我们将捕获鼠标、键盘操作的代码独立出来做成一个单独的进程,该进程想特定的消息队列发送捕获的鼠标、键盘操作,当前激活图像程序可以从该消息队列中提取相应的鼠标、键盘操作,然后据此执行后续的指令。以这种方式,能够将不同应用程序中,共性的部分提取出来,从而简化应用程序的设计和设计更加优化的共性处理程序。
消息队列潜在应用之升华
处理程序共性部分的一些方法:
库:通用的一些功能实现为库函数,对外提供定义良好的借口;应用程序在应用这些通用功能的时候,只需调用相应接口即可。
守护进程:将应用程序的共性部分提出出来实现为守护进程,通过某种形式的通信提供该守护进程服务的数据。
参考文献:《Linux程序设计第四版》
消息队列是在两个不相关进程间传递数据的一种简单、高效方式,她独立于发送进程、接受进程而存在。
图1消息队列通信机制示意图
首先从宏观的角度了解一下消息队列的工作机制。因为消息队列独立于进程而存在,为了区别不同的消息队列,需要以key值标记消息队列,这样两个不相关进程可以通过事先约定的key值进行消息收发。例如进程A向key消息队列发送消息,进程B从Key消息队列读取消息。在这一过程中主要涉及到四个函数:
#include<sys/msg.h>#消息队列相关函数及数据结构头文件
intmsgctl(intmsqid,intcmd,structmsqid_ds*buf);#控制消息队列函数
intmsgget(key_tkey,intmsgflg);#创建消息队列,key值唯一标识该消息队列
intmsgrcv(intmsqid,void*msg_ptr,size_tmsg_sz,longintmsgtype,intmsgflg);#接收消息
intmsgsnd(intmsqid,constvoid*msg_ptr,size_tmsg_sz,intmsgflg);#发送消息
下面结合代码实例,对上述过程进行分析(具体分析见代码注释)
#msg1.c接收端
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/msg.h>#包含消息队列相关函数及数据结构的头文件
structmy_msg_st{
longintmy_msg_type;
charsome_text[BUFSIZ];
};#消息格式
intmain()
{
intrunning=1;
intmsgid;
structmy_msg_stsome_data;
longintmsg_to_receive=0;
msgid=msgget((key_t)1234,0666|IPC_CREAT);#创建标识符为key=1234的消息队列,注意发送端与接收端该值的一致性
if(msgid==-1){
fprintf(stderr,“msggetfailedwitherror:%d\n”,errno);
exit(EXIT_FAILURE);
}#错误处理:msgget调用成功返回消息队列标识符,调用失败返回-1
while(running){
if(msgrcv(msgid,(void*)&some_data,BUFSIZ,msg_to_receive,0)==-1){#从消息队列接收消息,如果接收失败执行if语句并退出
fprintf(stderr,“msgrcvfailedwitherror:%d\n”,errno);
exit(EXIT_FAILURE);
}
printf(“Youwrote:%s”,some_data.some_text);
if(strncmp(some_data.some_text,“end”,3)==0){#如果接收到文本含有“end”,将running设置为0,效果是:退出while循环
running=0;
}
}
if(msgctl(msgid,IPC_RMID,0)==-1){#删除消息队列,如果删除失败执行if语句并退出
fprintf(stderr,“msgctl(IPC_RMID)failed\n”);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
#msg2.c发送端
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/msg.h>
#defineMAX_TEXT512
structmy_msg_st{
longintmy_msg_type;
charsome_text[MAX_TEXT];
};#消息格式,与接收端一致
intmain()
{
intrunning=1;
structmy_msg_stsome_data;
intmsgid;
charbuffer[BUFSIZ];
msgid=msgget((key_t)1234,0666|IPC_CREAT);#创建消息标识符key=1234的消息队列。如果该队列已经存在,则直接返回该队列的标识符,以便向该消息队列收发消息
if(msgid==-1){
fprintf(stderr,“msggetfailedwitherror:%d\n”,errno);
exit(EXIT_FAILURE);
}#错误处理,同接收者msg1
while(running){
printf(“Entersometext:“);
fgets(buffer,BUFSIZ,stdin);#由控制台输入文本,并将其存放在buffer之中
some_data.my_msg_type=1;#类型填充,在本例中没有特别含义
strcpy(some_data.some_text,buffer);#将buffer数据复制到some_text之中
if(msgsnd(msgid,(void*)&some_data,MAX_TEXT,0)==-1){#向消息队列发送消息,如果发送失败执行if语句并退出
fprintf(stderr,“msgsndfailed\n”);
exit(EXIT_FAILURE);
}
if(strncmp(buffer,“end”,3)==0){#如果发送的“end”,则在发送“end”之后,退出while,结束程序
running=0;
}
}
exit(EXIT_SUCCESS);
}
以下是在控制台模拟的结果:
$./msg2
Entersometext:hello
Entersometext:Howareyoutoday?
Entersometext:end
$./msg1
Youwrote:hello
Youwrote:Howareyoutoday?
Youwrote:end
$
消息队列潜在应用
图2消息队列在守护进程中的应用
如图2所示,假如有三个图形界面程序,他们分别对应进程1、进程2、进程3。这三个应用程序都需要鼠标、键盘操作,如果在每个进程都加入捕获鼠标、键盘操作的代码,那么一共需要三份这样的代码,有点浪费资源(内存空间)。如果我们将捕获鼠标、键盘操作的代码独立出来做成一个单独的进程,该进程想特定的消息队列发送捕获的鼠标、键盘操作,当前激活图像程序可以从该消息队列中提取相应的鼠标、键盘操作,然后据此执行后续的指令。以这种方式,能够将不同应用程序中,共性的部分提取出来,从而简化应用程序的设计和设计更加优化的共性处理程序。
消息队列潜在应用之升华
处理程序共性部分的一些方法:
库:通用的一些功能实现为库函数,对外提供定义良好的借口;应用程序在应用这些通用功能的时候,只需调用相应接口即可。
守护进程:将应用程序的共性部分提出出来实现为守护进程,通过某种形式的通信提供该守护进程服务的数据。
参考文献:《Linux程序设计第四版》
相关文章推荐
- linux C-(进程间通信 消息队列)
- [转]Linux环境进程间通信 -- 消息队列
- Linux进程间通信之消息队列
- Linux进程间通信——消息队列
- Linux进程间通信(二)——共享内存、消息队列
- Linux环境进程间通信系列(三):消息队列
- Linux进程间通信: 消息队列
- linux进程间通信(system v消息队列,阻塞式)实例
- Linux环境进程间通信(三):消息队列
- LINUX学习笔记15——进程间通信4消息队列
- Linux进程间通信: 消息队列
- Linux环境进程间通信(三):消息队列
- Linux环境进程间通信(三):消息队列
- linux进程间通信(posix消息队列)实例
- Linux环境进程间通信(三):消息队列
- linux进程间通信之消息队列
- Linux环境进程间通信(三)消息队列
- Linux高级进程间通信:消息队列
- Linux进程间通信——消息队列
- Linux环境进程间通信(三):消息队列