进程间通信——消息队列

消息队列是一种临时存储消息的队列, 完成进程间数据传递, 优先级队列。

与信号量对比: 都以内核对象来确保多进程访问同一个消息队列, 信号量进行进程同步控制, 消息队列发送实际数据。

与管道对比: 管道发送的数据没有类型, 读取数据端无差别从管道中按照数据的前后顺序读取数据;消息队列数据有类型,读端可以根据数据类型读取特定数据。管道是一个文件;消息队列是一个数据结构(类似于链表)。管道文件是存放在磁盘上的,访问速度慢,关机也会存在;消息队列是存在于内核中的内存,访问速度快,关机就没了。无名管道是跟随进程的,消息队列是跟随内核的,也就是说进程结束之后,无名管道就死了,但是消息队列还会存在。管道是数据流式存取,消息队列是数据块式存取。

消息队列的创建或获取
函数原型: int msgget(key_t key, int msgflg)
参数解析 :key是一个标识数据结构唯一的key键值,可以IPC_PRIVATE让内核自动给,也可以自己调用ftok函数绑定一个。
msgflg是创建消息队列的参数,有IPC_CREAT 和 IPC_EXCL 。单独使用IPC_CREAT,如果该消息队列已经存在,则打开该队列并返回,如果不存在,就新建一个返回。
成功返回标志消息队列的唯一的一个int,失败返回-1。


 消息队列的发送
函数原型:int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg)
参数解析 :msgid是消息队列号。
msgp是一个结构体的指针,这个结构体叫做msgbuf,这个是传输数据的数据块。
msgsz是传输的消息长度。
msgflg是传送方式的参数,没有可以设置为0。


消息队列的获取
函数原型:int msgrcv(int msgid,const void *msgp,size_t msgsz,long msgtyp,int msgflg)
参数解析:msgid是消息队列号。
msgp是一个结构体的指针,这个结构体叫做msgbuf,这个是传输数据的数据块。
msgsz是传输的消息长度。
msgtyp是用来表示当前进程拿数据的时候,只拿(msgbuf对象中的mtype)和传入的msgtyp一样的数据块(msgbuf对象)。
msgflg是传送方式的参数,没有可以设置为0。
成功返回长度,失败返回-1。


消息队列的销毁
函数原型: int msgctl(int msgid ,int cmd ,struct msgid_ds *buf)
参数解析:msgid是创建好的标识msg的int变量
cmd设置为IPC_RMID。
*buf设置为0。

进程B接收并打印进程A的数据

A

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>

struct msgbuff
{
    long type;
    char  data[128];
};

void main()
{
    int msgid = msgget((key_t)1234, IPC_CREAT | 0664);
    assert(msgid != -1);

    struct msgbuff  buff;
    buff.type = 1000;
    strcpy(buff.data, "hello");

    msgsnd(msgid, &buff, strlen(buff.data), 0);

    buff.type = 2000;
    strcpy(buff.data, "world");

    msgsnd(msgid, &buff, strlen(buff.data), 0);
}

B

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>

struct msgbuff
{
    long type;
    char  data[128];
};

void main()
{
    int msgid = msgget((key_t)1234, IPC_CREAT | 0664);
    assert(msgid != -1);

    struct msgbuff buff;
    memset(&buff, 0, sizeof(buff));

    msgrcv(msgid, &buff, 127, 1000, 0);

    printf("%s\n", buff.data);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值