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

进程间通信 IPC :管道、信号量、共享内存、消息队列、套接字

进程间通信,两个进程间传递信息

除了套接字,前面几个主要是在同一台主机上两个进程间通信

进程间通信(IPC):管道_♚陌上花开的博客-CSDN博客

进程间通信(IPC):信号量_♚陌上花开的博客-CSDN博客_ipc 信号量

进程间通信(IPC):共享内存_♚陌上花开的博客-CSDN博客

消息队列

通过ipcs查看消息队列

        消息队列与命名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。但使用消息队列并未解决我们在使用命名管道时遇到的一些问题,比如管道满时的阻塞问题。
        消息队列提供了一种在两个不相关的进程之间传递数据的相当简单且有效的方法。与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在,这消除了在同步命名管道的打开和关闭时可能产生的一些困难。
        消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。而且,每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型值的数据块。我们可以通过发送消息来几乎完全避免命名管道的同步和阻塞问题。更好的是,我们可以用一些方法来提前查看紧急消息。坏消息是:与管道一样,每个数据块都有一个最大长度的限制,系统中所有队列所包含的全部数据块的总长度也有一个上限。

一、消息队列原理

消息就是个结构体,结构体由自己定义

sruct mess
{
    long type;//消息队列类型
    //char buff[32];int buff[128];消息数据由自己定义
};

要指定消息类型,0不区分消息类型(定义的时候不能为0)

二、消息队列函数定义

三、函数

所需头文件

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

3.1 msgget()创建或者获取一个消息队列

int msgget(key_t key, int msgflg);

msgget() 创建或者获取一个消息队列

msgget() 成功返回消息队列 ID,失败返回-1

msqflg: IPC_CREAT

3.2 msgsnd()发送一条消息,添加消息

int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);

msgsnd() 发送一条消息

消息结构为:

struct msgbuf 1

{

        long mtype; // 消息类型, 必须大于 0

        char mtext[1]; // 消息数据 

};

msgsnd() 成功返回 0, 失败返回-1

msqp :消息的地址

msqsz: 指定 mtext 中有效数据的长度

msqflg:一般设置为 0 可以设置 IPC_NOWAIT

3.3 msgrcv()接收一条消息

ssize_t msgrcv(int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg); 

msgrcv() 接收一条消息

msgrcv() 成功返回 mtext 中接收到的数据长度, 失败返回-1

msgp : 存放消息的空间

msqsz : 消息的大小

msqtyp: 指定接收的消息类型,类型可以为 0 

msqflg: 一般设置为 0 可以设置 IPC_NOWAIT

3.4 msgctl()控制消息队列

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

msgctl() 控制消息队列

msgctl() 成功返回 0,失败返回-1

cmd: IPC_RMID

四、a创建消息队列写入数据,b读取信息

a.c文件

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

//定义的消息的结构体
struct mess
{
    long type;//消息类型,>0
    char buff[32];//消息数据
};

int main()
{
    int msgid = msgget((key_t)1234,IPC_CREAT|0600);//创建一个信号队列
    if(msgid == -1)
    {
        printf("msgget erro");//创建失败
        exit(1);
    }

    struct mess dt;//定义一个消息
    dt.type = 1;//代表1号消息类型
    strcpy(dt.buff,"hello1");

    //添加一个消息
    msgsnd(msgid,&dt,32,0);//有效数据长度只是消息数据的大小,不包括消息类型大小

    exit(0);

}
                                                                                             

消息队列由内核创建,进程结束,消息队列并不会结束,若要删除,必须明确定义

 b.c文件

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

//b与a相同的消息队列,可以将定义消息队列的结构体放在一个头文件中,就不需要再次定义
struct mess
{
    long type;
    char buff[32];
};

int main()
{
    int msgid = msgget((key_t)1234,IPC_CREAT|0600);//获取key值为1234的消息队列,没有则创建
    if(msgid == -1)
    {
        printf("msgget erro");//创建失败
        exit(1);
    }

    struct mess dt;//定义一个消息

    msgrcv(msgid,&dt,32,1,0);//接收消息

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

    exit(0);

}
入 --                                                                                                       

读取消息队列可以不设定消息类型,将消息类型写为0,不管什么类型的消息就都可以读取。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值