Linux进程间通信之消息队列

Linux进程间通信之消息队列

一、引言:管道只能在一端读一端写,有一些局限性,而消息队列功能性更强,可以相互发送数据。

二、什么是消息队列:
消息队列是消息的链接表,存储在内核中,由消息队列标识符标识。在本节中,我们把消息队列简称为队列,其标识符简称为队列ID。
在这里插入图片描述
消息队列由内核来管理,我们只需要掌握如何创建或打开一个现有的消息队列,如何将新消息添加至指定队列尾端和从队列中获取消息,和控制消息队列(如删除消息队列)。
注:每个消息由3部分组成:一个正的长整型类型的字段、一个非负的长度(nbytes)和实际数据字节数(对应的长度)。消息总时放在队列尾端。

三、特点:
1.消息队列时面向记录的,其中的消息具有特定的格式以及特定的优先级
2.消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
3.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

四、如何创建(打开),添加消息或获取消息队列等操作
消息队列相关API(包含头文件<sys/msg.h>):

NAME
       msgget - get a message queue identifier

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgget(key_t key, int msgflg);
       //返回值:成功返回队列ID;失败返回-1

①功能:创建或打开消息队列
②参数:
*key详细请看标识符和键。
*flag:消息队列的建立标志和存取权限(例:msgget(key,IPC_CREAT|0666 )
①如果键的值是IPC_PRIVATE。
②或者键的值不是IPC_PRIVATE,并且键所对应的消息队列不存在,同时标志中指定IPC_CREAT。
在这里插入图片描述
五、函数msgsnd和msgrcv
1.msgsnd:

NAME
       msgrcv, msgsnd - message operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgsnd(int msqid, const void *ptr, size_t size, int flg);
		//返回值:若成功,返回0,若失败,返回-1
       ssize_t msgrcv(int msqid, void *ptr, size_tsize, long typ,int flg);
		//返回值:若成功,成功返回消息数据长度;若失败,返回-1

①功能:添加消息。
②参数:
*msqid:消息队列的ID。
*ptr:该参数指向一个长整型数,它包含了正的整型消息类型,其后紧接着时消息数据(若nbytes是0,则无消息数据)。若发送的最长是512字节的,则可定义下列结构体:

           struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

*size:消息大小。
*flag:若为0,为默认方式:阻塞。

2.函数msgrcv:
①功能:读取消息。
②参数:
*msgid:消息队列的ID。
*ptr:如上文所示。
*size:消息的大小。
*type:消息的类型。
在这里插入图片描述
六、函数msgtcl:

NAME
       msgctl - message control operations

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgctl(int msqid, int cmd, struct msqid_ds *buf);
		//返回值:成功返回0;失败返回-1。

①功能:控制消息队列。
②参数:
*msqid:消息队列的ID。
*cmd:指定的队列要执行的命令,如 IPC_RMID可以删除该消息队列以及该队
列中所有的数据。
*buf:一般设置为NULL。

实例:
msgget.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct msgbuf {
        long mtype;       /* message type, must be > 0 */
        char mtext[128];    /* message data */
};


int main()
{
        key_t key;
        key = ftok(".",3);
        printf("key = %x\n",key);
        struct msgbuf buf;
        struct msgbuf sendbuf = {988,"hi!"};
        int msgID;
        msgID = msgget(key,IPC_CREAT|0666);
        int i = msgrcv(msgID,&buf,sizeof(buf.mtext),888,0);
        if(i == -1) {
                printf("get message error\n");
        }
        printf("data:%s\n",buf.mtext);
        int j = msgsnd(msgID,&sendbuf,sizeof(sendbuf.mtext),0);
        if(j == -1) {
                printf("send message error\n");
        }


        return 0;
}

msgsend.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
};


int main()
{
        int msgID;
        key_t key;
        key = ftok(".",3);
        printf("key = %x\n",key);
        struct msgbuf sendbuf = {888,"hallo from sendmsg.c"};
        struct msgbuf buf;
        msgID = msgget(key,IPC_CREAT|0666);
        int j = msgsnd(msgID,&sendbuf,sizeof(sendbuf.mtext),0);
        if(j == -1) {
                printf("send message error\n");
        }
        int i = msgrcv(msgID,&buf,sizeof(buf.mtext),988,0);
        if(i == -1) {
                printf("get message error\n\n");
        }
        printf("data:%s\n",buf.mtext);

        return 0;
}

编译运行getmsg.c,get阻塞。
在这里插入图片描述
编译运行sendmsg.c,get继续运行。
在这里插入图片描述
运行结果如下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值