linux进程通信之消息队列

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

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

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

键值函数结构如下:

#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“”

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值