linux进程通信之消息队列

来源:互联网 发布:淘宝游戏扶持号 编辑:程序博客网 时间:2024/06/14 12:51

进程通信信号量方式传送信息量有限,管道只能传送无格式字节流,无疑给程序开发带来不便,消息队列克服了这些缺点。

消息队列就是一个消息链表,可以把消息看做一个记录,具有特定格式,进程可以向其中按照一定规则添加新消息;另一些进程可以从消息队列读走消息。

消息队列只有在内核重新启动,或者人工删除才会消失。消息队列内核持续性需要消息队列在系统范围内拥有唯一个键值,所以,要获得一个消息队列的描述字,必须提供该消息队列的键值。

键值函数结构如下:

#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]# lsmsg  msg.c[root@localhost mesg]# ./msgkey =[ffffffff]recv msg =[this is a message][root@localhost mesg]# 
在运行结果中可以看到在消息队列中读取到了编号为当前进程id的消息“”this is a message“”

这就是最简单的消息队列演示。

 
原创粉丝点击