进程间通信(IPC)之 消息队列

消息队列,是消息的链表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识

特点:

  1. 消息队列是面向记录的,其中的消息具有特点的格式以及特点的优先级。

  1. 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。

  1. 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。

原型:

#include <sys/msg.h>
// 创建或打开消息对了;成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);

// 添加或发送消息;成功返回消息数据的长度,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flg);

//读取消息;成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type, int flg);

// 控制消息队列;成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

在下面两种情况下,msgget将创建一个新的消息队列:

  • 如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。

  • key参数为IPC_PRIVATE。

函数msgrcv在读取消息队列时,type参数有下面几种情况:

  • type = 0, 返回队列中的第一个消息

  • type > 0, 返回队列中消息类型为type的第一个消息

  • type < 0, 返回队列中消息类型值小于或等于type 绝对值的消息,如果有多个,则取类型值最小的消息。

下面实现双方的收发

get.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf {
        long mtype;       /* message type, must be > 0 */
        char mtext[256];    /* message data */
};

int main()
{
        struct msgbuf readBuf;
        key_t key;
        key = ftok(".", 'z');
        printf("key=%x\n",key);
        int msgId = msgget(key, IPC_CREAT|0777);
        if(msgId == -1){
                printf("get que failluer\n");
        }
        memset(&readBuf,0,sizeof(struct msgbuf));
        msgrcv(msgId, &readBuf, sizeof(readBuf.mtext), 888, 0);
        printf("read from que: %s\n", readBuf.mtext);
        struct msgbuf sendBuf = {988, "thank you for reach"};
        msgsnd(msgId, &sendBuf, strlen(sendBuf.mtext), 0);

        msgctl(msgId, IPC_RMID, NULL);

        return 0;
}

send.c

#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf {
        long mtype;       /* message type, must be > 0 */
        char mtext[256];    /* message data */
};

int main()
{
        struct msgbuf sendBuf = {888, "this is message from que"};
        struct msgbuf readBuf;
        memset(&readBuf,0,sizeof(struct msgbuf));
        key_t key;
        key = ftok(".", 'z');
        printf("key=%x\n",key);
        int msgId = msgget(key, IPC_CREAT|0777);

        if(msgId == -1){
                printf("get que failluer\n");
        }
        msgsnd(msgId, &sendBuf, strlen(sendBuf.mtext), 0);

        msgrcv(msgId, &readBuf, sizeof(readBuf.mtext), 988, 0);
        printf("read from get: %s\n", readBuf.mtext);
        msgctl(msgId, IPC_RMID, NULL);

        return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值