消息队列创建和通信

消息队列,信号量,共享内存通称为system-V IPC,在系统中他们都是用一种名为key的键值来做唯一标识,他们被创建后,不会因为进程的退出而消失,而会持续的存在,除非调用特殊的函数或命令删除。

ftok函数
在这里插入图片描述
1)pathname:在一个项目里面,所有进程都在同一路径里面,pathname指的是一个路径。
2)proj_id:IPC的标识,表示key值
在这里插入图片描述

当路径和IPC的标识都一样时,创建出来的key值是一样的。
key的作用:申请对应传输机制的空间资源和确定传输机制
消息队列:消息队列需要的空间,确定传输机制
共享内存:共享内存需要的空间,确定传输机制
信号量:信号量需要的空间,确定传输机制

注意:当要重复创建不同的但是有相同的IPC时,需要不同的key值
不一样的key值,就可以创建多个相同的IPC
当key值相同,操作的就是同一个IPC对象

例子:创建两个不同的key值:

#define IPC_MASK_A 1
#define IPC_MASK_B 2

int main()
{
   key_t key_a = ftok("./",IPC_MASK_A);
   key_t key_b = ftok("./",IPC_MASK_B);
   if(key_a == -1 || key_b == -1)
   {
       perror("ftok");

       return -1;
   }
   else
   {
       printf("%d---%d\n",key_a,key_b);
   }

    return 0;
}

如何用key值创建消息队列-----msgget
在这里插入图片描述
mode:访问的权限只有读和写没有执行(0666)
查看和删除当前系统的IPC对象
在这里插入图片描述
示例代码:

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

#define IPC_MASK_A 1
#define IPC_MASK_B 2

int main()
{
   key_t key_a = ftok("./",IPC_MASK_A);
   key_t key_b = ftok("./",IPC_MASK_B);
   if(key_a == -1 || key_b == -1)
   {
       perror("ftok");

       return -1;
   }
   else
   {
       printf("%d---%d\n",key_a,key_b);
   }

    int msg_queue_id_a = msgget(key_a,IPC_CREAT | 0666);
    int msg_queue_id_b = msgget(key_b,IPC_CREAT | 0666);
    if(msg_queue_id_a == -1 || msg_queue_id_b == -1)
    {
        perror("msgget");
        return -1;
    }
    else
    {
        printf("%d---%d\n",msg_queue_id_a,msg_queue_id_b);
    }

    return 0;
}

消息队列如何通信
在这里插入图片描述
在这里插入图片描述
示例代码:

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

#define MSG_LENGTH 24
#define IPC_MASK_A 1
#define IPC_MASK_B 2
#define MSG_MASK   1L

int main()
{
   key_t key_a = ftok("./",IPC_MASK_A);
   key_t key_b = ftok("./",IPC_MASK_B);
   if(key_a == -1 || key_b == -1)
   {
       perror("ftok");

       return -1;
   }
   else
   {
       printf("%d---%d\n",key_a,key_b);
   }

    int msg_queue_id_a = msgget(key_a,IPC_CREAT | 0666);
    int msg_queue_id_b = msgget(key_b,IPC_CREAT | 0666);
    if(msg_queue_id_a == -1 || msg_queue_id_b == -1)
    {
        perror("msgget");
        return -1;
    }
    else
    {
        printf("%d---%d\n",msg_queue_id_a,msg_queue_id_b);
    }


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


    /*调用msgsnd函数发送消息*/
    memset(&msg_inf_send,0,sizeof(msg_inf_send));
    memset(&msg_inf_rev,0,sizeof(msg_inf_rev));

    msg_inf_send.mtype = MSG_MASK;

        memset(msg_inf_send.mtext,0,MSG_LENGTH);
        memset(msg_inf_rev.mtext,0,MSG_LENGTH);
        
        printf("请输入要发送的消息:");
        scanf("%s",msg_inf_send.mtext);

        int msgsnd_ret = msgsnd(msg_queue_id_a,&msg_inf_send,strlen(msg_inf_send.mtext),0);
        if(msgsnd_ret == -1)
        {
            perror("msgsnd");

            return -1;
        }
        else
        {
            printf("发送消息成功!!!!\n");
        }

        /*调用msgrcv读取消息*/
        int msgrcv_ret = msgrcv(msg_queue_id_a,&msg_inf_rev,MSG_LENGTH,MSG_MASK,0);
        if(msgrcv_ret == -1)
        {
            perror("msgrcv");
            return -1;
        }
        else
        {
            printf("消息是:%s\n",msg_inf_rev.mtext);
        }
    int msgctl_ret_a = msgctl(msg_queue_id_a,IPC_RMID,NULL);
    int msgctl_ret_b = msgctl(msg_queue_id_b,IPC_RMID,NULL);
    if(msgctl_ret_a == -1 || msgctl_ret_b == -1)
    {
        perror("msgctl");
        return -1;
    }

    return 0;
}

控制设置消息队列的接口
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

邢饱饱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值