操作系统 消息队列,系统中进程间通信
进程间的通信-消息队列什么是消息队列?消息,用于将数据从一个进程发送到另一个进程。但是它只将数据发送到一个“队列”中,而没有指定哪个进程将接收它。消息队列独立于发送消息的过程和接收消息的过程。每个消息队列都有一个标识符,只有拥有这个标识符的进程才能进入队列获取消息。消息队列有最大长度限制:MSGMNB。消息队列中单个消息的最大长度限制。获取消息队列msgget函数:获取或创建一个消息队列。原型:int msgget(key_t key,int msgflg);参数:key:消息队列ID。Msgflg:访问权限。IPC_CREAT——如果键不存在,创建一个类似于open函数的O_CREAT。(来源见补充1)IPC_EXCL——如果键存在,会返回一个失败,类似于open函数的O_EXCL。(出处见补充1。)返回值:Success:正整数,即消息队列标识符。失败:返回-1并设置错误号。补充:Linux API快速检查手册-Msgget Msgget(2)-发送Linux手册页消息msgsnd功能:发送消息,即将消息放入某个消息队列中。原型:int msgsnd (int msgqid,constvoid * msgp,size _ t msgsz,int msgflg);参数:msgid:消息队列标识符。Msgp:消息指针。消息类型需要自己的定义。但是它的第一个结构成员要求是long int。示例:struct my_msg_st {
长整型消息类型;/*消息的类型,取0,可以在接收消息时使用*/
/*其他信息*/
Gsz:消息的长度(不包括第一个成员msg_type)msgflg:IPC_NOWAIT:如果包含此选项,当消息队列满时,将不发送消息,立即返回-1。相反,如果不包含此选项,当消息队列已满时,此进程将被挂起,直到消息队列可用。返回值:成功:返回0。失败:返回-1。补充:Linux手册页消息接收msgrcv函数原型:ssize _ tmsgrcv (intmsqid,void * msgp,size _ tmsgsz,longmsgtype,intmsgflg);函数:从消息队列接收消息。参数msgid:消息队列标识符。Msgp:用于接收消息的缓存。Msgsz:要接收的消息的长度(不包括其第一个成员)msgtype:指定接收到的消息的类型0:从消息队列中获取第一条消息,实现顺序接收(先查找后接收)。大于0:从消息队列中获取第一条相同类型的消息。小于0:从消息队列中获取消息类型小于或等于msgtype绝对值的第一条消息。Msgflg:如果包含IPC_NOWAIT,当当前消息队列摘要中没有指定类型的消息时,将立即返回-1。如果不包括IPC_NOWAIT,当消息队列中没有指定类型的消息时,此进程将被挂起,直到收到指定类型的消息。返回值:Success:返回接收消息的长度(不包括第一个成员msg_type)。失败:返回-1。消息控制msgctl函数原型:intmsgctl (intmsqid,intcmd,structmsqid _ ds * buf);功能:用于控制和修改消息队列的基本属性。参数:msqid:消息队列标识符。Cmd:执行的控制命令。详见补充。Buf:详见补充。返回值:成功:返回0。失败:返回-1。补充:msgctl(2)—Linux手册页示例例1:程序1:向消息队列发送消息,程序2接收。消息_发送1.c
#包含sys/types.h
#包含sys/ipc.h
#包含sys/msg.h
#包含系统/统计信息
#包含fcntl.h
#包含stdio.h
#包含stdlib.h
#包含字符串. h
#定义消息_大小80
结构my_msg_st {
长整型消息类型;
char MSG[MSG _ SIZE];
};
int main(void){
int msgid
int ret
结构my _ msg _ st msg
msgid=msgget((key_t)1235,0666 IPC _ CREAT);
if (msgid==-1) {
printf(msgget失败!\ n’);
出口(1);
}
msg . msg _ type=1;
strcpy(msg.msg, Hello world!);//发送什么
ret=msgsnd(msgid,msg,MSG_SIZE,0);
if (ret==-1) {
printf(msgsnd失败!\ n’);
出口(1);
}
返回0;
}msg_recv2.c
#包含sys/types.h
#包含sys/ipc.h
#包含sys/msg.h
#包含系统/统计信息
#包含fcntl.h
#包含stdio.h
#包含stdlib.h
#定义消息_大小80
结构我的邮件地址
长整型消息类型;
char MSG[MSG _ SIZE];
};
int main(void)
{
int msgid
内部ret
结构我的消息
msgid=msg get((key _ t)12350666 IPC _ CREAT);
if (msgid==-1) {
printf(msgget失败!\ n’);
出口(1);
}
味精。msg _ type=0;
ret=msgrcv(msgid,msg,MSG_SIZE,0,0);
if (ret==-1) {
printf(msgrcv失败!\ n’);
出口(1);
}
printf(已接收:%s\n ,消息。味精);
ret=msgctl(msgid,IPC_RMID,0);//全局性的删除-IPC_RMID
if (ret==-1) {
printf(msgctl(IPC_RMID)失败!\ n’);
出口(1);
}
返回0;
}
示例2:进程1:循环等待用户输入字符串,将收到的每个字符串发送给进程2,直到用户输入出口。进程2:接收进程一发来的信息,并打印输出,直到接收到出口。消息_发送
#包含sys/types.h
#包含sys/ipc.h
#包含系统/消息. h
#包含系统/统计信息
#包含fcntl.h
#包含标准视频
#包含标准库
#包含字符串。h
#定义消息_大小80
结构我的邮件地址
长整型消息类型;
char MSG[MSG _ SIZE];
};
int main(void){
int msgid
内部ret
结构我的消息
msgid=msg get((key _ t)12350666 IPC _ CREAT);
if (msgid==-1) {
printf(msgget失败!\ n’);
出口(1);
}
while(1) {
fgets(msg.msg,sizeof(msg.msg),stdin);
味精。msg _ type=1;
ret=msgsnd(msgid,msg,MSG_SIZE,0);
if (ret==-1) {
printf(msgsnd失败!\ n’);
出口(1);
}
if (strncmp(msg.msg, exit ,4)==0) {
打破;
}
}
返回0;
}msg_recv.c
#包含sys/types.h
#包含sys/ipc.h
#包含系统/消息. h
#包含系统/统计信息
#包含fcntl.h
#包含标准视频
#包含标准库
#定义消息_大小80
结构我的消息st {
长整型消息类型;
char MSG[MSG _ SIZE];
};
int main(void){
int msgid
内部ret
结构我的消息
//第二个参数为权限控制
msgid=msg get((key _ t)12350666 IPC _ CREAT);
if (msgid==-1) {
printf(msgget失败!\ n’);
出口(1);
}
while(1) {
味精。msg _ type=0;
ret=msgrcv(msgid,msg,MSG_SIZE,0,0);
if (ret==-1) {
printf(msgrcv失败!\ n’);
出口(1);
}
printf(已接收:%s\n ,消息。味精);
if (strncmp(msg.msg, exit ,4)==0) {
打破;
}
}
ret=msgctl(msgid,IPC_RMID,0);
if (ret==-1) {
printf(msgctl(IPC_RMID)失败!\ n’);
出口(1);
}
返回0;
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。