linux进程通信之消息队列
2017-09-15 16:39
447 查看
进程通信信号量方式传送信息量有限,管道只能传送无格式字节流,无疑给程序开发带来不便,消息队列克服了这些缺点。
消息队列就是一个消息链表,可以把消息看做一个记录,具有特定格式,进程可以向其中按照一定规则添加新消息;另一些进程可以从消息队列读走消息。
消息队列只有在内核重新启动,或者人工删除才会消失。消息队列内核持续性需要消息队列在系统范围内拥有唯一个键值,所以,要获得一个消息队列的描述字,必须提供该消息队列的键值。
键值函数结构如下:
返回文件名对应的键值
pathname:文件名
proj:项目名不为0即可
打开消息队列函数结构:
返回值:与键值对应的消息队列描述字
key:键值,有ftok获得。
msgflg:标志位
常用标志位:
IPC_CREAT
创建新的消息队列
IPC_EXCL
与IPC_CREAT一同使用,表示如果创建的消息队列已经存在,返回错误。
IPC_NOWAIT
读写消息队列无法满足要求时不阻塞。
以下两种情况将创建消息队列:
1)没有与键值对应的消息队列,并且msgflg有IPC_CREAT参数。
2)key参数为IPC_PRIVATE。
发送消息函数结构:
向消息队列发送一条消息
msgqid 消息队列描述字。
msgp 存放消息结构。
msgsz 消息数据的长度。
msgflag 发送标志 有意义的发送标志为IPC_NOWAIT,指明在消息队列乜有足够空间容纳要发送的消息时,是否等待。
消息格式
struct msgbuf
{
long type //消息类型 >0
char ext[1] //消息数据的首地址
}
接收消息函数结构如下:
从msgid代表的队列中读取一个msgtyp类型的消息,并把消息存储在msgp指向的msgbuf结构中,再成功读取一条消息后,消息队列中这条消息将被删除。
多说无益直接上代码:
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
struct msg_buf
{
int mtype;
char data[255];
};
int main()
{
key_t key; //消息队列键值
int msgid; //消息队列描述符
int ret;
struct msg_buf msgbuf; //消息队列结构
key=ftok("/tmp/2",'a'); //创建消息队列 获取键值
printf("key =[%x]\n",key); //打印键值
msgid=msgget(key,IPC_CREAT|0666); /*通过文件对应*/
if(msgid==-1)
{
printf("create error\n");
return -1;
}
msgbuf.mtype = getpid(); //消息编号为自身进程ID (只要大于0就可以)
strcpy(msgbuf.data,"this is a message");
ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT); //向消息队列发送 编号为自身ID 内容为 this is a message的消息
if(ret==-1)
{
printf("send message err\n");
return -1;
}
memset(&msgbuf,0,sizeof(msgbuf)); //清空消息队列为接收做准备
ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);//接收消息队列中编号为自身进程ID的消息
if(ret==-1)
{
printf("recv message err\n");
return -1;
}
printf("recv msg =[%s]\n",msgbuf.data); //打印接受的消息
}执行代码查看运行状况:
[root@localhost mesg]# ls
msg msg.c
[root@localhost mesg]# ./msg
key =[ffffffff]
recv msg =[this is a message]
[root@localhost mesg]# 在运行结果中可以看到在消息队列中读取到了编号为当前进程id的消息“”this is a message“”
这就是最简单的消息队列演示。
消息队列就是一个消息链表,可以把消息看做一个记录,具有特定格式,进程可以向其中按照一定规则添加新消息;另一些进程可以从消息队列读走消息。
消息队列只有在内核重新启动,或者人工删除才会消失。消息队列内核持续性需要消息队列在系统范围内拥有唯一个键值,所以,要获得一个消息队列的描述字,必须提供该消息队列的键值。
键值函数结构如下:
#include <sys/types.h> #include <sys/ipc.h> key_t ftok(char *pathname,char proj);功能:
返回文件名对应的键值
pathname:文件名
proj:项目名不为0即可
打开消息队列函数结构:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget(key_t key,int msgflg);功能:
返回值:与键值对应的消息队列描述字
key:键值,有ftok获得。
msgflg:标志位
常用标志位:
IPC_CREAT
创建新的消息队列
IPC_EXCL
与IPC_CREAT一同使用,表示如果创建的消息队列已经存在,返回错误。
IPC_NOWAIT
读写消息队列无法满足要求时不阻塞。
以下两种情况将创建消息队列:
1)没有与键值对应的消息队列,并且msgflg有IPC_CREAT参数。
2)key参数为IPC_PRIVATE。
发送消息函数结构:
#include <sys/types.h> #include <sys/ipc.h> #include <sysmsg.h> int megsend(int msgid,struct msgbuf *msgp,int msgsz,int msgflg);功能:
向消息队列发送一条消息
msgqid 消息队列描述字。
msgp 存放消息结构。
msgsz 消息数据的长度。
msgflag 发送标志 有意义的发送标志为IPC_NOWAIT,指明在消息队列乜有足够空间容纳要发送的消息时,是否等待。
消息格式
struct msgbuf
{
long type //消息类型 >0
char ext[1] //消息数据的首地址
}
接收消息函数结构如下:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgrcv(int msgid,struct msgbuf*msgp,int msgsz,long msgtpy,int msgflg);功能:
从msgid代表的队列中读取一个msgtyp类型的消息,并把消息存储在msgp指向的msgbuf结构中,再成功读取一条消息后,消息队列中这条消息将被删除。
多说无益直接上代码:
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
struct msg_buf
{
int mtype;
char data[255];
};
int main()
{
key_t key; //消息队列键值
int msgid; //消息队列描述符
int ret;
struct msg_buf msgbuf; //消息队列结构
key=ftok("/tmp/2",'a'); //创建消息队列 获取键值
printf("key =[%x]\n",key); //打印键值
msgid=msgget(key,IPC_CREAT|0666); /*通过文件对应*/
if(msgid==-1)
{
printf("create error\n");
return -1;
}
msgbuf.mtype = getpid(); //消息编号为自身进程ID (只要大于0就可以)
strcpy(msgbuf.data,"this is a message");
ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT); //向消息队列发送 编号为自身ID 内容为 this is a message的消息
if(ret==-1)
{
printf("send message err\n");
return -1;
}
memset(&msgbuf,0,sizeof(msgbuf)); //清空消息队列为接收做准备
ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);//接收消息队列中编号为自身进程ID的消息
if(ret==-1)
{
printf("recv message err\n");
return -1;
}
printf("recv msg =[%s]\n",msgbuf.data); //打印接受的消息
}执行代码查看运行状况:
[root@localhost mesg]# ls
msg msg.c
[root@localhost mesg]# ./msg
key =[ffffffff]
recv msg =[this is a message]
[root@localhost mesg]# 在运行结果中可以看到在消息队列中读取到了编号为当前进程id的消息“”this is a message“”
这就是最简单的消息队列演示。
相关文章推荐
- Linux进程通信之System V消息队列
- LINUX_C编程实战—第十章《进程间的通信》-消息队列
- Linux进程通信之POSIX消息队列
- Linux消息队列进程通信的介绍
- Linux进程间的通信方式----消息队列
- linux进程通信:消息队列
- linux进程通信之消息队列
- linux进程通信——消息队列(相互通信)
- Linux--进程通信之消息队列的双向通信
- Linux进程通信---消息队列 代码实现
- linux进程通信---消息队列
- Linux下进程之间通过消息队列通信小程序示例
- linux进程间的通信(C): 消息队列
- Linux进程之间通信消息队列
- UNIX/LINUX编程学习之进程通信--消息队列
- linux消息队列进程通信
- Linux进程通信之消息队列
- linux编程---进程通信---消息队列
- linux进程通信之消息队列
- Linux — IPC进程通信之消息队列详解