多进程 消息队列练习

A向B发消息,B收到并打印,B向A发消息,A收到并打印,用多进程实现,程序A中父进程向程序B中父进程发消息,程序B中父进程收到消息并打印,程序B中子进程向程序A中子进程发消息,程序A中子进程收到消息并打印;

不同进程间通信用消息队列实现,程序A和程序B创建连接同一个消息队列,程序A中父进程向消息队列中发类型1的消息,程序B中父进程读取消息队列中类型1的消息并打印;程序B中子进程向消息队列中发类型2的消息,程序A中子进程从消息队列中读类型2的消息并打印;

进程退出机制:输入端输入'q'时退出;程序A父进程从终端收到'q'时,阻塞等待程序A子进程退出,并向程序B中父进程发送'q',程序B中父进程收到'q',阻塞等待程序B中子进程退出;程序B中子进程从终端收到'q'时,向程序A中子进程发送'q',并退出进程,程序A中子进程收到'q'时退出。

程序A代码如下

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

//定义消息包类型
struct msgbuf
{
    long mtype;  //消息类型
    char mtext[32]; //消息内容
};

int main(int argc, char const *argv[])
{
    //创建消息队列
    //计算key值
    key_t key = ftok("/home/ytc01/HuaQingYuanJian/20230208study/work/",1);
    if(-1 == key)
    {
        perror("ftok");
        return -1;
    }
    //创建消息队列
    int msqid = msgget(key,IPC_CREAT | 0664);
    if(-1 == msqid){
        perror("msgget");
        return -1;
    }

    //创建父子进程
    pid_t pid = fork();
    if(pid > 0){
        //父进程向消息队列中写类型1
        struct msgbuf snd;
        snd.mtype = 1;

        while(1){
            bzero(snd.mtext,sizeof(snd.mtext));

            //从终端获取消息
            printf("A端请输入:");
            fgets(snd.mtext,sizeof(snd.mtext),stdin);
            snd.mtext[strlen(snd.mtext)-1] = 0;

            if(strcasecmp(snd.mtext,"q") == 0){
                msgsnd(msqid,&snd,sizeof(snd.mtext),1);
                if(-1 == wait(NULL)){
                    perror("wait");
                    return -1;
                }
                break;
            }
            //向消息队列中发送数据
            if(msgsnd(msqid,&snd,sizeof(snd.mtext),1) < 0)
            {
                perror("msgsnd");
                return -1;
            }
        }

    }else if(0 == pid){
    
        struct msgbuf rcv;

        //子进程从消息队列中读类型2
        while (1)
        {
            memset(&rcv,0,sizeof(rcv));
            //从消息队列中读取数据

            //阻塞方式读取,消息队列中第一条消息类型为2的消息
            if(msgrcv(msqid,&rcv,sizeof(rcv.mtext),2,0) < 0)
            {
                perror("msgrcv");
                break;
            }
            if(strcasecmp(rcv.mtext,"q") == 0){
                break;
            }else{
                printf("A reply mtype:%ld  mtext=%s\n",rcv.mtype,rcv.mtext);
            }
        }

    }else{
        perror("fork");
        return -1;
    }

    
    return 0;
}

程序B代码如下

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

//定义消息包类型
struct msgbuf
{
    long mtype;  //消息类型
    char mtext[32]; //消息内容
};

int main(int argc, char const *argv[])
{
    //创建消息队列
    //计算key值
    key_t key = ftok("/home/ytc01/HuaQingYuanJian/20230208study/work/",1);
    if(-1 == key)
    {
        perror("ftok");
        return -1;
    }
    //创建消息队列
    int msqid = msgget(key,IPC_CREAT | 0664);
    if(-1 == msqid){
        perror("msgget");
        return -1;
    }
    
    //创建父子进程
    pid_t pid = fork();
    if(pid > 0){
        //父进程从消息队列中读类型1
        struct msgbuf rcv;

        while (1)
        {
            memset(&rcv,0,sizeof(rcv));
            //从消息队列中读取数据

            //阻塞方式读取,消息队列中第一条消息类型为1的消息
            if(msgrcv(msqid,&rcv,sizeof(rcv.mtext),1,0) < 0)
            // if(msgrcv(msqid,&rcv,sizeof(rcv.mtext),1,IPC_NOWAIT) < 0)

            {
                perror("msgrcv");
                break;
            }if(strcasecmp(rcv.mtext,"q") == 0){
                if(-1 == wait(NULL)){
                    perror("wait");
                    return -1;
                }
                break;
            }else{
                printf("B reply mtype:%ld  mtext=%s\n",rcv.mtype,rcv.mtext);
            }
        }

    }else if(0 == pid){
        //子进程向消息队列中写类型2
        struct msgbuf snd;
        snd.mtype = 2;

        while(1){
            bzero(snd.mtext,sizeof(snd.mtext));

            //从终端获取消息
            printf("B端请输入:");
            fgets(snd.mtext,sizeof(snd.mtext),stdin);
            snd.mtext[strlen(snd.mtext)-1] = 0;

            if(strcasecmp(snd.mtext,"q") == 0){
                msgsnd(msqid,&snd,sizeof(snd.mtext),2);
                return -1;
                //break;
            }

            //向消息队列中发送数据
            if(msgsnd(msqid,&snd,sizeof(snd.mtext),2) < 0)
            {
                perror("msgsnd");
                return -1;
            }
        }

    }else{
        perror("fork");
        return -1;
    }

    

    return 0;
}

效果展示如下图

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值