系统性红斑狼疮紫癜:利用消息队列实现进程间通信
来源:百度文库 编辑:中财网 时间:2024/05/05 19:26:00
所谓消息功能,是指由一个进程产生并送出的消息,被放在一个叫做“消息队列”的列中管理,然后由接收方从消息队列中取出消息,这么一种功能。(先入先出)
做一个例子程序看看:
下面的两个程序分为发送方和接收方。发送方将自己的PID和从标准输入输入的一个字符串送至消息队列,接收方把消息队列中所有的PID和字符串读出,并输出至标准输出。
/* msend.c */
#include
#include
#include
#include
int main()
{
int msqid;
key_t msgkey;
struct msgbuf
{
long mtype;
char mdata[256];
};
struct msgbuf msgdata , *p ;
p = &msgdata ;
printf("Enter message : ");
fflush( stdin ); /* 刷新标准输入缓冲区 */
gets( p->mdata ); /* 输入字符串 */
p->mtype = getpid();
msgkey = ftok ( "mrecv" , 'a' ); /* 计算标识符 */
msqid = msgget( msgkey , IPC_CREAT | 0666 ) ; /* 建立消息队列 */
msgsnd( msqid , p , sizeof(p->mdata) , 0 ); /* 送消息 */
return 0;
}
/* mrecv.c */
#include
#include
#include
#include
int main()
{
int msqid;
key_t msgkey;
struct msgbuf
{
long mtype;
char mdata[256];
};
struct msgbuf msgdata , *p ;
p = &msgdata ;
msgkey = ftok( "mrecv" , 'a' ); /* 计算标识符 */
msqid = msgget( msgkey , IPC_CREAT | 0666 ) ; /* 取得消息队列的ID */
while(1)
{
msgrcv( msqid , p , sizeof(p->mdata) , 0 , 0 ) ; /* 读消息 */
printf("Message received from %ldn%sn" , p->mtype , p->mdata );
}
return 0;
}
执行例:
% msend
Enter message : Hello , world
%msend
Enter message : I am Syuu I
%mrecv
Message received from 321
Hello , world
Message received from 326
I am Syuu I
使用消息功能,可分如下几步
发送方:
1.生成消息队列,取得ID。
2.向消息队列送消息。
接收方:
1.根据标识符,取得ID。
2.从消息队列接收消息。
3.删除消息队列。
例程序相对来说比较简单。我们就不解释了。
消息队列的使用方法以及函数的构造等等基本上和上一章所讲的共享内存的使用方法一样。可参考上一章来理解本章内容。
说说出现的函数:
#include
#include
#include
int msgget( key_t msgkey , int flag );
取得一个消息队列的ID,如不存在则建立。
返回值: 成功时:消息队列的ID
失败时:-1
int msgsnd( int msqid , struct msgbuf *msgp , size_t msgsiz , int msgflag );
向消息队列送消息
返回值: 成功时:0
失败时:-1
msqid是消息队列的ID,size_tmsgsiz是结构体成员mdata的大小,msgflag与上一章所讲的共享内存的flag起一样的作用,不过,当这个参数为IPC_NOWAIT的时候,如果消息队列已满,则返回错误值。如果不为IPC_NOWAIT,在消息队列已满 的情况下,会一直等到消息队列有空地方的时候再发送。
注意这里的这个 struct msgbuf *msgp 。要求的格式如下:
struct msgbuf
{
long mtype;
char mdata[256];
};
longmtype在这里我们用来保存本进程的PID。mdata则是保存要发送的数据。由于mdata的大小不一定(根据实际需要定义),所以这个结构体并没有事先定义好。但是我们定义这个结构体的时候一定要遵循这个规定。你可以改的,只有mdata的大小,和结构体的名称。尽量不要修改结构体成员的名称和类型。实际上,根据mtype,我们还可以有所选择地接受消息。这在下面将会谈到。
int msgrcv( int msqid , struct msgbuf *msgp , size_t msgsiz , long msgtyp , int msgflag );
从消息队列取得一个消息
返回值: 成功时:0
失败时:-1
msqid , *msgp , msgsiz不用说了。longmsgtyp是结构体msgbuf的mtype成员。msgflag与上述一样。只不过为IPC_NOWAIT的时候,如果消息队列是空的,则等到有消息可读的时候再读。当不为IPC_NOWAIT的时候,如果消息队列是空的,则返回错误值(与字面上理解的有些相反)
同样地,为了控制管理消息队列,一样有一个函数msgctl()如下:
#include
#include
#include
int msgctl( int msqid , int cmd , struct msqid_ds *buf );
返回值: 成功时:0
失败时:-1
cmd所指定的值与共享内存部分相同。
做一个例子程序看看:
下面的两个程序分为发送方和接收方。发送方将自己的PID和从标准输入输入的一个字符串送至消息队列,接收方把消息队列中所有的PID和字符串读出,并输出至标准输出。
/* msend.c */
#include
#include
#include
#include
int main()
{
int msqid;
key_t msgkey;
struct msgbuf
{
long mtype;
char mdata[256];
};
struct msgbuf msgdata , *p ;
p = &msgdata ;
printf("Enter message : ");
fflush( stdin ); /* 刷新标准输入缓冲区 */
gets( p->mdata ); /* 输入字符串 */
p->mtype = getpid();
msgkey = ftok ( "mrecv" , 'a' ); /* 计算标识符 */
msqid = msgget( msgkey , IPC_CREAT | 0666 ) ; /* 建立消息队列 */
msgsnd( msqid , p , sizeof(p->mdata) , 0 ); /* 送消息 */
return 0;
}
/* mrecv.c */
#include
#include
#include
#include
int main()
{
int msqid;
key_t msgkey;
struct msgbuf
{
long mtype;
char mdata[256];
};
struct msgbuf msgdata , *p ;
p = &msgdata ;
msgkey = ftok( "mrecv" , 'a' ); /* 计算标识符 */
msqid = msgget( msgkey , IPC_CREAT | 0666 ) ; /* 取得消息队列的ID */
while(1)
{
msgrcv( msqid , p , sizeof(p->mdata) , 0 , 0 ) ; /* 读消息 */
printf("Message received from %ldn%sn" , p->mtype , p->mdata );
}
return 0;
}
执行例:
% msend
Enter message : Hello , world
%msend
Enter message : I am Syuu I
%mrecv
Message received from 321
Hello , world
Message received from 326
I am Syuu I
使用消息功能,可分如下几步
发送方:
1.生成消息队列,取得ID。
2.向消息队列送消息。
接收方:
1.根据标识符,取得ID。
2.从消息队列接收消息。
3.删除消息队列。
例程序相对来说比较简单。我们就不解释了。
消息队列的使用方法以及函数的构造等等基本上和上一章所讲的共享内存的使用方法一样。可参考上一章来理解本章内容。
说说出现的函数:
#include
#include
#include
int msgget( key_t msgkey , int flag );
取得一个消息队列的ID,如不存在则建立。
返回值: 成功时:消息队列的ID
失败时:-1
int msgsnd( int msqid , struct msgbuf *msgp , size_t msgsiz , int msgflag );
向消息队列送消息
返回值: 成功时:0
失败时:-1
msqid是消息队列的ID,size_tmsgsiz是结构体成员mdata的大小,msgflag与上一章所讲的共享内存的flag起一样的作用,不过,当这个参数为IPC_NOWAIT的时候,如果消息队列已满,则返回错误值。如果不为IPC_NOWAIT,在消息队列已满 的情况下,会一直等到消息队列有空地方的时候再发送。
注意这里的这个 struct msgbuf *msgp 。要求的格式如下:
struct msgbuf
{
long mtype;
char mdata[256];
};
longmtype在这里我们用来保存本进程的PID。mdata则是保存要发送的数据。由于mdata的大小不一定(根据实际需要定义),所以这个结构体并没有事先定义好。但是我们定义这个结构体的时候一定要遵循这个规定。你可以改的,只有mdata的大小,和结构体的名称。尽量不要修改结构体成员的名称和类型。实际上,根据mtype,我们还可以有所选择地接受消息。这在下面将会谈到。
int msgrcv( int msqid , struct msgbuf *msgp , size_t msgsiz , long msgtyp , int msgflag );
从消息队列取得一个消息
返回值: 成功时:0
失败时:-1
msqid , *msgp , msgsiz不用说了。longmsgtyp是结构体msgbuf的mtype成员。msgflag与上述一样。只不过为IPC_NOWAIT的时候,如果消息队列是空的,则等到有消息可读的时候再读。当不为IPC_NOWAIT的时候,如果消息队列是空的,则返回错误值(与字面上理解的有些相反)
同样地,为了控制管理消息队列,一样有一个函数msgctl()如下:
#include
#include
#include
int msgctl( int msqid , int cmd , struct msqid_ds *buf );
返回值: 成功时:0
失败时:-1
cmd所指定的值与共享内存部分相同。
JAVA 队列的实现
操作系统课程设计 模拟进程利用双向邮箱通信
进程通信
进程间的通信方式 四种
编程实现对话框间的通信
进程队列的概念和形式?
一个用C++实现的队列问题
链栈和链队列的实现
消息缓冲通信机制
消息缓冲通信机制
进程创建及进程通信
两个进程如何通信
TAO进程间的共享内存通信如何进行?
有谁知道不同型号交换机怎样实现vlan间通信
利用红外线通信的技术参数
课设链式队列操作实现怎么弄?
利用声卡可以实现
如何利用互联网发布消息?
如何利用互联网发布消息?
基于进程通信(IPC)机制的聊天程序的设计,能够实现在同一台服务器的多用户之间的聊天。
利用vb实现文件分割
利用C++如何编程实现?
利用C++如何编程实现?
哪位大虾知道ucos的消息队列或是邮箱会不会被挤爆