【IO】使用消息队列完成两个进程之间相互通信

news2024/12/25 10:36:45

目录

1、使用消息队列完成两个进程之间相互通信

2、共享内存实现两个进程之间的通信

3、思维导图


1、使用消息队列完成两个进程之间相互通信

//msgsnd.c
#include <myhead.h>

// 要发送的消息类型
struct msgbuf
{
    long mtype;
    char mtext[1024];
};

// 定义一个宏,为后面需要传入数据的大小
#define SIZE sizeof(struct msgbuf) - sizeof(long)

int main(int argc, char const *argv[])
{
    // 1.创建出一个key值,用于产生消息队列
    key_t key = ftok("/", 'k');
    if (key == -1)
    {
        perror("ftok error");
        return -1;
    }

    // 2.通过生成的key创建出一个消息队列对象
    int msqid = msgget(key, IPC_CREAT | 0664);
    if (msqid == -1)
    {
        perror("msqid error");
        return -1;
    }

    // 向消息队列中存放消息
    struct msgbuf buf;

    // 创建父子进程
    int pid = fork();
    if (pid < 0)
    {
        perror("fork error");
        return -1;
    }
    else if (pid == 0)
    {
        // 子进程,用于读取消息队列中类型为2的数据
        while (1)
        {
            // 读取消息队列中类型为1的数据
            msgrcv(msqid, &buf, SIZE, 2, 0);
            if (strcmp(buf.mtext, "quit") == 0)
            {
                break;
            }
            // 直接输出到终端,读到了什么内容
            printf("\n接收到的数据为:%s\n", buf.mtext);
        }
    }

    // 父进程
    // 向消息队列中存放类型为1数据
    while (1)
    {
        // 发送消息为1的数据
        buf.mtype = 1;
        printf("请输入消息内容>>>");
        fgets(buf.mtext, SIZE, stdin);
        buf.mtext[strlen(buf.mtext) - 1] = 0; // 将回车变成'\0'

        // 将数据以阻塞的形式发送到消息队列中
        msgsnd(msqid, &buf, SIZE, 0);
        printf("发送成功\n");
    }

    wait(NULL);
    return 0;
}
//msgrecv.c
#include <myhead.h>

// 要接收的消息类型
struct msgbuf
{
    long mtype;
    char mtext[1024];
};

// 定义一个宏,为后面需要传入数据的大小
#define SIZE sizeof(struct msgbuf) - sizeof(long)

int main(int argc, char const *argv[])
{
    // 1.创建出一个key值,用于打开消息队列
    key_t key = ftok("/", 'k');
    if (key == -1)
    {
        perror("ftok error");
        return -1;
    }

    // 2.打开消息队列对象
    int msqid = msgget(key, IPC_CREAT | 0664);
    if (msqid == -1)
    {
        perror("msqid error");
        return -1;
    }

    // 向消息队列中存放消息
    struct msgbuf buf;

    // 创建父子进程
    int pid = fork();

    if (pid < 0)
    {
        perror("fork error");
        return -1;
    }
    else if (pid == 0)
    {
        // 子进程,用于读取消息队列中类型为1的数据
        while (1)
        {
            // 读取消息队列中类型为1的数据
            msgrcv(msqid, &buf, SIZE, 1, 0);

            if (strcmp(buf.mtext, "quit") == 0)
            {
                break;
            }
            // 直接输出到终端,读到了什么内容
            printf("\n接收到的数据为:%s\n", buf.mtext);
        }

        // 删除消息队列
        if (msgctl(msqid, IPC_RMID, NULL) == -1)
        {
            perror("msgctl error");
            return -1;
        }
        exit(EXIT_SUCCESS);
    }

    // 父进程
    // 向消息队列中存放类型为2数据
    while (1)
    {
        // 向消息队列中存放类型为2的数据
        buf.mtype = 2;
        printf("请输入消息内容>>>");
        fgets(buf.mtext, SIZE, stdin);
        buf.mtext[strlen(buf.mtext) - 1] = 0; // 将回车变成'\0'

        // 将数据以阻塞的形式发送到消息队列中
        msgsnd(msqid, &buf, SIZE, 0);
        printf("发送成功\n");
    }

    wait(NULL);
    return 0;
}

 输出结果如下:实现两个进程之间的通信

2、共享内存实现两个进程之间的通信

//shmsnd.c
#include<myhead.h>
#include<sys/user.h>
int main(int argc, char const *argv[])
{
    //创建key值用于创建共享内存段
    key_t key = ftok("/",'t');
    if(key == -1)
    {
        perror("ftok error");
        return -1;
    }

    printf("key = %d\n",key);

    //2、创建一个共享内存的对象
    int shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
    if(shmid == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n",shmid);

    //3、将共享内存段映射到程序中来
    char *addr = (char *)shmat(shmid,NULL,0);
    //参数1:共享内存id号
    //参数2:系统自动映射对齐页
    //参数3:对共享内存的操作权限为读写权限

    printf("addr = %p\n",addr); //输出映射的地址

    //读出共享内存中的数据
    printf("消息为:%s",addr);

    sleep(5);
    if(shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }

    //删除共享内存
    if(shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("shmctl error");
        return -1;
    }

    while(1);

    return 0;
}
//shmrecv.c
#include<myhead.h>
#include<sys/user.h>
int main(int argc, char const *argv[])
{
    //创建key值用于创建共享内存段
    key_t key = ftok("/",'t');
    if(key == -1)
    {
        perror("ftok error");
        return -1;
    }

    printf("key = %d\n",key);

    //2、创建一个共享内存的对象
    int shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
    if(shmid == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid = %d\n",shmid);

    //3、将共享内存段映射到程序中来
    char *addr = (char *)shmat(shmid,NULL,0);
    //参数1:共享内存id号
    //参数2:系统自动映射对齐页
    //参数3:对共享内存的操作权限为读写权限

    printf("addr = %p\n",addr); //输出映射的地址

    //向共享内存中写入数据
    strcpy(addr,"hello a hua qing yuan jian\n");

    sleep(5);

    //取消映射关系
    if(shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }

    
    while(1);
    return 0;
}

输出结果如下:

3、思维导图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1988136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

html5各行各业官网模板源码下载(3)

文章目录 1.来源2.源码模板2.1 HTML5好看的酷酷的个人简历、个人主页、个人网站源码2.2 html实现我的博客文章相册源码2.3 html实现好看的塔罗牌、十二星座运势网站源码 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/1…

语音转文字大盘点,Windows版Top3,你选对了吗?

现在的工作压力可不是盖的&#xff0c;老板们总希望我们能像超人一样&#xff0c;工作速度快得飞起。如果做不到&#xff0c;可能就得把位置让给别人了。不过别担心&#xff0c;有了语音转文字的软件&#xff0c;咱们的工作效率就能大大提升。那咱们应该选哪款免费的语音转文字…

免费【2024】springboot 房屋租赁系统的设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

如何通过【腾讯云 AI 代码助手】快速解决商城项目难题

文章目录 引言开发环境介绍从 IDE 插件市场安装 腾讯云AI代码助手实战问题一&#xff1a;如何使用RabbitMQ的死信队列来实现关闭订单的操作&#xff1f;并编写java代码问题二&#xff1a;在解决库存问题时&#xff0c;如何使用Redis的分布式锁来实现呢&#xff1f; 获得的帮助与…

【iOS】GCD详细总结

GCD详细总结 1. GCD简介2. GCD任务和队列任务队列 (dispatch是派遣的意思&#xff09;队列的创建方法和获取方法 3.我的总结&#xff1a;同步和异步函数&#xff0c;并行和并发队列同步异步函数串行并发队列是否开启新线程&#xff0c;串行还是并发执行任务&#xff0c;如何分析…

【网络技术】堆叠通用部署

相关文章推荐 点击查看&#xff1a; 华为交换机堆叠技术 华为交换机组建堆叠案例 【技术分享】堆叠交换机替换指导 交换机为什么要堆叠&#xff1f; 配置交换机1 <HUAWEI> system-view [HUAWEI] sysname Switch1 [Switch1] interface stack-port 0/1 [Switch1-stack…

一文读懂 服务器

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我…

分数取模怎么办

我们遇到负数的话要先加上 mod 再取模 那么遇到分数的话怎么办 分数则由分子乘以分母的逆元&#xff0c;然后再对积取模。 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.h> using namespace std;// 如果用杨辉三角形做的话空间会爆炸 // 我是sb&#xff0c;只有三…

Find My充气宝|苹果Find My技术与充气宝结合,智能防丢,全球定位

随着人们生活水平的提高&#xff0c;汽车已经走进了千家万户&#xff0c;汽车的普及也导致了停车位资源的稀缺。很多新手司机在停车和行车时经常会碰到轮胎被扎或者气压不足的问题&#xff0c;最近的骑行文化盛行&#xff0c;很多的骑手也会带着自己的山地自行车开启一段骑行之…

[Git][分支设计规范]详细讲解

目录 0.概览1.master分支2.release分支3.develop分支4.feature分支5.hotfix分支 0.概览 以下是常用的分支和环境的搭配&#xff0c;可视情况而定不同的策略 分支名称适用环境master主分支生产环境release预发布分支预发布/测试环境develop开发分支开发环境feature需求开发分支本…

第6章>>实验8:PS(ARM)端Linux RT与PL端FPGA之间(通过FIFO队列进行通信和交互)-《LabVIEW ZYNQ FPGA宝典》

1、实验内容 上一节实验里面介绍的Memory存储器通道比较适合在PS端和PL端之间传递数组或者向量等数据&#xff0c;也就是多个相同类型的元素&#xff0c;如果要传递像ADC采集这样的连续数据流&#xff0c;Memory存储器通道就不是很合适了。 本节实验我们向大家讲解如何借助FIFO…

加速 Spring Boot 3.3 迁移

1. 关键要点 为什么你应该升级你的服务迁移到 Spring Boot 3.3 时需要更新的内容OpenRewrite 如何帮助使升级更轻松、更快捷 2. 前言 现在Spring Boot 已经到了3.3&#xff0c;但是你在哪里&#xff1f;在过去的 3.x 版本更新中&#xff0c;我们看到了许多新功能&#xff0c;…

SAP EPPM-CPM(商业项目管理)模块功能演示:创建主项目

今天跟大家展示一下如何通过SAP CPM维护商业项目以及计划结构。 CPM的主要操作界面是SAP之前推出的新一代UX Fiori&#xff0c;如果需要在CPM操作&#xff0c;可分配SAP提供的标准复合角色&#xff1a;SAP_BPR_CPD_USER_1。 因为在CPM模块的宗旨是构建一个项目的全局视角门户…

触屏交互设备的安全风险

现实中的绝大多数电子设备都具有交互性&#xff0c;而现在越来越多的公共场合有布置越来越多的带触屏的交互设备&#xff0c;功能有简单的&#xff0c;有复杂的&#xff0c;布置的场所和应用的场合也各有不同&#xff0c;几乎在任何一个大型公共场合都可以看到这样的设备&#…

Android14音频进阶调试之命令播放mp3/aac非裸流音频(八十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更…

如何理解openfoam案例里面的blockMesh文件里面的simpleGrading

总结&#xff1a; simpleGrading参数分为xyz三个方向。如果你想使得网格在某个方向上更密集&#xff0c;可以在simpleGrading中将该方向的渐变率设置为小于 1 .更稀疏则设置大于1. 一、案例 比如我这个爆炸案例&#xff1a; 对应的blockMeshDIct文件如下&#xff1a; // 定…

第20周:Pytorch文本分类入门

目录 前言 一、前期准备 1.1 环境安装导入包 1.2 加载数据 1.3 构建词典 1.4 生成数据批次和迭代器 二、准备模型 2.1 定义模型 2.2 定义示例 2.3 定义训练函数与评估函数 三、训练模型 3.1 拆分数据集并运行模型 3.2 使用测试数据集评估模型 总结 前言 &#x1…

游戏盾是什么,如何保护网络游戏的安全

在数字化浪潮的推动下&#xff0c;网络游戏已成为人们休闲娱乐不可或缺的一部分。然而&#xff0c;随着游戏行业的蓬勃发展&#xff0c;网络安全问题也日益严峻&#xff0c;黑客攻击频发&#xff0c;给游戏玩家和游戏运营商带来了巨大困扰。为了应对这些挑战&#xff0c;应用加…

机器学习·L2W3-模型评估

模型评估 划分数据集为训练集、验证集、测试集 60%训练集、20%测试集和验证集 x_train,x_,y_train,y_train_test_split(X_train,y_train,test_size0.4) x_cv,x_test,y_cv,y_testtrain_test_split(x_train,y_train,test_size0.5)交叉验证-模型选择 使用交叉验证计算模型的损失…

新来的小姐姐,微软便笺程序打不开了

网管小贾 / sysadm.cc 公司新来了一位小姐姐&#xff0c;听说跟老板沾点关系。 这一天老板出差&#xff0c;午休时大家趁着小姐姐去取外卖&#xff0c;开始了各自的调侃。 部门主管丽姐开了个头&#xff0c;当着众人先抱怨上了。 “你们看看&#xff0c;你们看看&#xff0c;…