匿名管道的使用示例

目录

整体框架

 通信步骤

创建管道

​编辑创建子进程&关闭相应的fd

​编辑 

 进程间通信

父子进程通信之间四种场景

 实现父亲读,孩子写的进程间通信

管道通信的使用场景样例实现


整体框架

 通信步骤

创建管道

 

 pipe的参数为输出型参数,返回读写端的fd存储到pipefd的数组中,创建成功,函数返回值为0;否则为-1。

 

创建子进程&关闭相应的fd

 

 

 

 进程间通信

 

父子进程通信之间四种场景

1. 如果读端读取完管道中的所有数据,如果写端没有发送新的数据,该读端的进程只能等待;

2.如果写端写满了管道,而读端没有来的及去读,此时的写端无法继续去写

 

 

 

65535=2^16==2^12 * 2^4 == 4KB*16 

3. 如果关闭了写端,读取完毕管道数据,在读,read就会返回0,表示读到了文件的末尾。

4. 写端一直在写,读端关闭,会发生什么呢?写端在写就没有任何意义了。OS不会维护无意义、低效率、或者浪费资源的事情!OS会杀死一直在写的进程!OS会通过信号来终止进程,13)SIPIPE。

 实现父亲读,孩子写的进程间通信

//C++函数头文件c取代.h为了更好的兼容C++
#include<iostream>
#include<cerrno>
#include<cstring>
#include<cassert>
#include<string>//系统调用函数的头文件为.h
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>int main()
{//让不同的进程看到同一个资源 步骤:1~3//任何一种进程通信中,一定要 先 保证不同进程之间看到同一份资源  步骤:4int pipefd[2]={0};//1.创建管道int ret=pipe(pipefd);if(ret<0){std::cout<<"pipe error:"<<errno<<":"<<strerror(errno)<<std::endl;return 1;}//验证管道是否创建成功std::cout<<"pipefd[0]:"<<pipefd[0]<<std::endl;//pipefd数组下标为0的表示读端std::cout<<"pipefd[1]:"<<pipefd[1]<<std::endl;//pipefd数组下标为1的表示写端//2.创建子进程pid_t id=fork();assert(id!=-1);if(id==0){//子进程//3.关闭不需要的fd,让父进程进行读取,让子进程去写入close(pipefd[0]);//4.开始通信 ——结合某种场景// const std::string nameStr="Hello ,我是子进程";// int cnt=1;// char buffer[1024]={0};int cnt=0;while(true){char x='X';write(pipefd[1],&x,1);std::cout << "Cnt: " << ++cnt<<std::endl;sleep(1);//break;// snprintf(buffer,sizeof(buffer),"%s,计数器:%d,我的pid:%d",nameStr.c_str(),cnt++,getpid());// write(pipefd[1],buffer,strlen(buffer));// sleep(10);}close(pipefd[1]);exit(0);}//父进程//3.关闭不需要的fd,让父进程进行读取,让子进程去写入close(pipefd[1]);//4.开始通信    ——结合某种场景char buffer[1024]={0};int cnt=0;while(true){//sleep(5);int n=read(pipefd[0],buffer,sizeof(buffer)-1);if(n>0){buffer[n]='\0';std::cout<<"我是父进程,child give me message:"<<buffer<<std::endl;}else if(n==0){std::cout<<"我是父进程,读到了文件末尾"<<std::endl;break;}else {std::cout<<"我是父进程,读取异常"<<std::endl;exit(1);}sleep(1);if(cnt++>5)break;}close(pipefd[0]);int status=0;waitpid(id,&status,0); std::cout<<"sig:"<<(status&0x7F)<<std::endl;return 0;
}

管道通信的使用场景样例实现

【应用场景】

父进程要创建若干个子进程,每一个子进程配对一个管道,用来进行与父进程之间的通信;父亲通过管道,对子进程发送信号,子进程接受到信号后,依据信号来执行相应的任务!

【问题分析】

  1. 如何动态创建多个子进程?答:循环控制!
  2. 如何建立一个管道匹配一个子进程?答:再循环里面定义临时变量pipefd[2],这样就可以确保每一个创建的子进程找到对应读写的fd!
  3. 由于子进程会复制父进程的所有管理对象里的内容,这样,第二个以及后面的子进程就可以得到前面子进程与父进程管道之间读写fd信息,如何确保创建的管道只对应一个子进程,不受其它子进程的影响?答:因为,父进程只能关闭读端,不能关闭写端,所以要在父进程中保存之前子进程创建管道的写端的fd,后面的创建的子进程就可以得到之前子进程的读端的fd,在依次关闭就可以了!
  4. 父进程如何知道给哪一个子进程来分配任务?答:为了管理多个管道和子进程与父亲的关系,方法是先描述,在组织--》描述:父亲要得到子进程的fd才能找到相应的子进程,还要得到该子进程所对应管道写端的文件描述符fd--》组织:定义EndPoint结构体存储子进程的id和文件描述符fd;在最后,每创建一个子进程,就将相应的信息存储到vector<EndPoint>容器中。
  5. 如何指定相对应的任务呢?答:定义task对象,里面保存要有的任务,对每一个任务进行编号处理。用户通过输入数字来指定相对应的任务!

【代码实现思路】

  1. 首先需要创建子进程,并创建对应的管道;
  2. 进程间通信,输入对应执行任务指令;
  3. 进程退出,回收进程。

 代码实现:lesson14/2. CtrlProcess · 杰编程/LinuxCode - 码云 - 开源中国 (gitee.com)

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提升问卷数据的有效性?

问卷调查法是收集数据的宝贵工具&#xff0c;可以为商业、社会科学和医疗保健等众多领域的决策过程提供真实可靠的数据信息。然而&#xff0c;问卷数据的准确性和可靠性是影响最终结论的关键因素&#xff0c;而他们取决于问卷设计和数据收集过程的质量。在本文中&#xff0c;我…

zabbix proxy的配置及zabbix实现高可用(监控 windows,java应用,SNMP等)

目录 zabbix proxy 分布式代理服务器部署zabbix proxy 代理服务器部署 Zabbix 高可用集群Zabbix 监控 Windows 系统Zabbix 监控 java 应用Zabbix 监控 SNMP zabbix proxy 分布式代理服务器 zabbix 分布式代理服务器&#xff0c;可以代替zabbix server 采集性能和可用性数据。z…

nginx七层代理和四层转发的理解

先来理解一下osi七层模型 应用层 应用层是ISO七层模型的最高层&#xff0c;它直接与用户和应用程序交互&#xff0c;提供用户与网络的接口。它包括各种应用协议&#xff0c;如HTTP、FTP、SMTP等&#xff0c;用于实现特定应用的功能和通信表示层 表示层…

学生成绩分析项目

数据采集 导入必要的库 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns加载数据集 df pd.read_csv(D:\\桌面\\数据\\student_marks.csv)显示数据框的前几行 # 显示数据框的形状 print("Shape of the dataframe:", df.shape)#显示…

【运维】GitLab相关配置优化等

默认 Git 设置 http post 的缓存为 1MB&#xff0c;使用命令将git的缓存设为500M&#xff0c;重新配置一下postBuffer值 git config --global http.postBuffer 524288000 解决方法2&#xff1a;直接修改config参数&#xff0c; windows: ./git/config中&#xff0c;加入以下…

Freertos-mini智能音箱项目---IO扩展芯片PCA9557

项目上用到的ESP32S3芯片引脚太少&#xff0c;选择了PCA9557扩展IO&#xff0c;通过一路i2c可以扩展出8个IO。这款芯片没有中断输入&#xff0c;所以更适合做扩展输出引脚用&#xff0c;内部寄存器也比较少&#xff0c;只有4个&#xff0c;使用起来很容易。 输入寄存器 输出寄存…

【Linux】高级IO(二)

文章目录 高级IO&#xff08;二&#xff09;I/O多路转接之pollpoll服务器 I/O多路转接之epollepoll相关函数epoll工作原理epoll回调机制epoll服务器epoll的优点 高级IO&#xff08;二&#xff09; I/O多路转接之poll poll也是系统提供的一个多路转接接口 poll系统调用也可以…

基于go-zero的api服务刨析并对比与gin的区别

zero路由与gin的区别 官网go-zero go-zero是一个集成了各种工程实践的微服务框架&#xff0c;集多种功能于一体&#xff0c;如服务主要的API服务&#xff0c;RPC服务等。除了构建微服务工程外&#xff0c;zero也是一款性能优良的web框架&#xff0c;也可以构建单体web应用。 …

最新AI创作系统V5.0.2+支持GPT4+支持ai绘画+实时语音识别输入+文章资讯发布功能+用户会员套餐

最新AI创作系统V5.0.2支持GPT4支持ai绘画实时语音识别输入文章资讯发布功能用户会员套餐&#xff01; AI创作系统一、源码系统介绍二、AI创作系统程序下载三、安装教程四、主要功能展示五、更新日志 AI创作系统 1、提问&#xff1a;程序已经支持GPT3.5、GPT4.0接口 2、支持三种…

Maven 配置本地jar,通过下载第三方jar包,然后手动配置maven jar包依赖 例如:IKExpression

说明&#xff1a;有时候有一些jar包 maven中央仓库和阿里云仓库没有收录的jar包需要手动下载至本地进行手动添加maven依赖&#xff0c;就拿 IK表达式 IKExpression jar 包来说 第一步 下载IKExpression 包 没有这个包的同学可以点击下载阿里云盘分享 第二步 找到自己项目本地…

Redis 五种基本数据结构及基本使用

一、数据结构 二、使用 2.1 String 的使用 Redis String 一个键对应一个值&#xff0c;并且是二进制安全的&#xff0c;值可以是图片或者序列化后的对象。 一个键最大能存储 512 MB。 2.1.1 set 命令的使用 set key value127.0.0.1:6379> set name yunhu OK 127.0.0.1:…

二十三种设计模式第十四篇--策略模式

策略模式&#xff1a;主要围绕一个类的行为或者其算法在运行时更改&#xff0c;也是一种行为型模式。 在软件开发中&#xff0c;我们经常遇到需要根据不同的情况选择不同算法或行为的情况。传统的做法是使用大量的条件语句来实现这种逻辑&#xff0c;但这样的实现方式往往难以…