进程间通信-----消息队列

消息队列

  • 消息队列是System IPC对象的一种。
  • 消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等。
  • 多个进程通过消息队列的标识符对消息数据进行传送。
  • 消息列队可以按照类型来发送/接收消息。

案例要求:


两个进程通过消息队列,轮流将键盘输入的字符串发送给对方,接收并打印对方发送的消息。


进程A

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
typedef struct   //要发送的消息存放在此结构体中
{
        long mtype;           //消息类型,用大于零的整数表示
        char mtext[64];     //消息内容
} MSG;

#define LEN (sizeof(MSG) - sizeof(long))   //计算消息内容的大小
#define TypeA 100           //定义两个不同的消息类型
#define TypeB 200
int main()
{
        key_t key;       //键值
        int msgid;      //标识符
        MSG buf;
        
        if((key = ftok(".",'q'))== -1)  //创建消息队列的键值
        {
                 perror("ftok");
                 exit(-1);
        }
        if((msgid = msgget(key,IPC_CREAT|0666)) < 0)  //创建消息队列的标识符
        {
                 perror("msgget");
                 exit(-1);
        }
        while(1)
     {
                buf.mtype = TypeB;  //先向B发送消息
                printf("input>");
                fgets(buf.mtext,64,stdin);//将键盘写入的数据存入buf.mtext中
                msgsnd(msgid,&buf,LEN,0);//将buf中的数据发送到消息列队中
                if(strcmp(buf.mtext,"quit\n") == 0)break; //输入quit时,退出循环
        if(msgrcv(msgid,&buf,LEN,TypeA,0) < 0)//A接收消息队列中的数据
        {
                perror("msgrcv");
                exit(-1);
        }
        if(strcmp(buf.mtext,"quit\n") ==0) //判断接收的消息中是否有quit
        {
                msgctl(msgid,IPC_RMID,0);
                exit(0);
        }
        printf("recv from clientB :%s",buf.mtext); //打印接收到的信息

    }
           return 0;


}
~


进程B
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
typedef struct   //要发送的消息存放在此结构体中
{
        long mtype;
        char mtext[64];
} MSG;

#define LEN (sizeof(MSG) - sizeof(long))
#define TypeA 100
#define TypeB 200
int main()
{
        key_t key;
        int msgid;
        MSG buf;

        if((key = ftok(".",'q'))== -1) //创建消息队列的键值,通信进程间KEY应相同
        {
                 perror("ftok");
                 exit(-1);
        }
        if((msgid = msgget(key,IPC_CREAT|0666)) < 0)
        {
                 perror("msgget");
                 exit(-1);
        }
        while(1)
     {
        if(msgrcv(msgid,&buf,LEN,TypeB,0) < 0)//B接收消息队列中的数据
        {
                perror("msgrcv");
                exit(-1);
        }
        if(strcmp(buf.mtext,"quit\n") ==0)//判断接收的消息中是否有quit
        {
                msgctl(msgid,IPC_RMID,0);  //删除消息队列
                exit(0);
        }
                printf("recv from clientA :%s",buf.mtext);//打印从A传的数据
                buf.mtype = TypeA;//B给A发送
                printf("input>");
                fgets(buf.mtext,64,stdin);//将键盘写入的数据存入buf.mtext中
                msgsnd(msgid,&buf,LEN,0);//B给A发送消息
                if(strcmp(buf.mtext,"quit\n") == 0)break;
    }
           return 0;
}

编译运行

book@100ask:~/msg$ ./clientA
input>Hello     //A第一次发送
recv from clientB :welcome   //A第一次接收
input>123            //A第二次发送
recv from clientB :456  //A第二次接收
input>over             //A第三次发送
book@100ask:~/msg$     //接收到quit后结束

book@100ask:~/msg$ ./clientB
recv from clientA :Hello    //B第一次接收
input>welcome               //B第一次发送
recv from clientA :123         //B第二次接收
input>456                       //B第二次发送
recv from clientA :over       //B第三次接收
input>quit                      //B发送quit
book@100ask:~/msg$              //发送quit后结束

程序的结构流程如下

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值