Linux进程间通信:消息队列(msg)

目录

 ★ 什么是消息队列?

 ★ 流程摘要

 ★ msgget函数

 ★ msgsnd函数

 ★ msgrcv函数

 ★ msgctl函数

 ★ 消息队列相关指令


 ★ 什么是消息队列?

  • 是Linux的一种通信机制,这种通信机制传递的数据具有某种结构,而不是简单的字节流;
  • 消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构;
  • 向消息队列中写数据,实际上是向这个数据结构中插入一个新结点;从消息队列汇总读数据,实际上是从这个数据结构中删除一个结点;
  • 消息队列提供从一个进程向另外一个进程发送一块数据的方法;
  • 消息队列也有管道一样的不足,就是每个数据块的最大长度是有上限的,系统上全体队列的最大总长度也有一个上限。

 

 ★ 流程摘要

① 创建消息队列,使用msgid接收标识符;

② 写入内容到消息队列;

③ 读取消息队列内容;

④ 根据实际情况是否删除消息队列

 ★ msgget函数

 msgget函数:创建消息队列/获取消息队列标识符(使用msgid接收标识符)

函数原型:

int msgget(key_t key, int msgflg);

key:需要通信的进程双方建立起的队列标识码,使用ftok函数来获取;

msgflg:访问权限;

返回值:如果成功,返回值将是消息队列标识符(非负整数),否则为-1,errno表示错误。

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

int main()
{
        key_t key = ftok("msg1.c",1);
        int msgid = msgget(key,IPC_CREAT|0666);
        if(msgid == -1){
                printf("msgget error!\n");
        }
        printf("msgget success!msgid=%d\n",msgid);
        return 0;
}

 ★ msgsnd函数

msgsnd函数:写入内容到消息队列

函数原型:

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

int msqid:消息队列标识码,即msgid;

const void *msgp:指向消息类型的指针,原型是一个结构体,如下:

struct msgbuf {
         long mtype;    //消息类型      
         char mtext[1]; //消息内容   
};

size_t msgsz:发送消息的字节数;

int msgflg:如果为0,直到发送完成函数才返回,即阻塞发送;IPC_NOWAIT,消息没有发送完成,函数也返回,即非阻塞发送;

返回值:成功返回0,失败返回-1;

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

struct msgbuf{
        long mtype;
        char mtext[32];
};
int main()
{
        key_t key = ftok("msg1.c",1);
        int msgid = msgget(key,IPC_CREAT|0666);
        if(msgid == -1){
                printf("msgget error!\n");
        }
        printf("msgget success!msgid=%d\n",msgid);

//      int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
        struct msgbuf snd = {1,"hellobaby!"};
        msgsnd(msgid,&snd,sizeof(snd.mtext),0);

        return 0;
}

 ★ msgrcv函数

msgrcv函数:读取消息队列内容

函数原型:

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

 int msqid:消息队列标识码,即msgid;

void *msgp:指向消息类型的指针;

size_t msgsz:读取消息的字节数;

long msgtyp:接收消息的类型/标识;

Int msgflg:0表示阻塞读取;IPC_NOWAIT表示非阻塞读取;

返回值:成功返回接收到消息的长度,失败返回-1;

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

struct msgbuf{
        long mtype;
        char mtext[32];
};
int main()
{
        key_t key = ftok("msg1.c",1);
        int msgid = msgget(key,IPC_CREAT|0666);
        if(msgid == -1){
                    printf("msgget error!\n");
        }
        printf("msgget success!msgid=%d\n",msgid);

//      ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

        struct msgbuf snd = {1,"hellobaby!"};
        msgrcv(msgid,&snd,sizeof(snd.mtext),1,0);
        printf("mtype:%ld\n",snd.mtype);
        printf("mtext:%s\n",snd.mtext);

        return 0;
}

 ★ msgctl函数

msgctl函数: 删除消息队列

函数原型:

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

int msqid:消息队列标识码,即msgid;

int cmd:IPC_STAT 读取消息队列的属性,然后把它保存在buf指向的缓冲区; 

             IPC_SET 设置消息队列的属性,这个值取至buf中参数

             IPC_RMID 删除消息队列;

struct msqid_ds *buf: 消息队列的缓冲区,如果参数cmd写IPC_RMID时,此缓冲区内写NULL就行。

返回值:成功返回0,失败返回-1.

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

int main()
{
//      int msgctl(int msqid, int cmd, struct msqid_ds *buf);

        msgctl(3,IPC_RMID,NULL); //上面示例代码的msgid=3

        return 0;

 ★ 消息队列相关指令

ipcs :显示消息队列,共享内存,信号量通信的相关数据;

ipcs -q:只显示消息队列信息;

ipcrm -q:删除消息队列标识符。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D.•

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值