当前位置:网站首页>父子进程间通信(一) —— 管道的作用原理 + 管道创建函数pipe
父子进程间通信(一) —— 管道的作用原理 + 管道创建函数pipe
2022-04-21 20:52:00 【abs(ln(1+NaN))】
进程之间可能存在协同工作的场景,一个进程把自己的数据交付给另一个进程,让其进行处理,如:
cat file.txt | wc -l
执行cat指令会触发一个进程,执行完cat file.txt 能读取到file.txt文件的内容,然后将读取结果通过管道交付给下一个进程wc,让wc来统计file.txt文件有多少行内容
这就是进程间通信的方式之一 —— 管道
目录
一、进程间通信的本质前提
因为进程之间具有独立性,一个进程是看不到另一个进程的资源的!!

两者在这种水火不容的情况下,要如何进行通信呢?? 答案是 给他们一块公共资源(公共内存)
这块内存不属于任何进程!!如果属于进程A,那么进程B能访问到这块公共资源,这就打破了进程的独立性原则,所以这块公共资源属于OS

所以进程间通信的前提就是 有一块双方都能访问的公共资源,这块资源是属于OS的
二、管道的作用原理
下面以父子进程为例,介绍管理的作用方式
一个进程如果要向磁盘写入数据,那么必会先得到写入文件的文件描述符fd ——》 找到对应文件的struct file ——》 调用文件操作函数 ——》向文件内核缓冲区写入数据 ——》OS定时调用驱动函数 write_disk 向磁盘写入数据

现在我们通过fork()创建了一个子进程,子进程会拷贝父进程的进程控制块和struct files,此时两个进程就有了一块公共资源 struct file

现在我们不触发底层的写入函数,那么数据就会留在文件内核缓冲区,此时我们的子进程就可以读取到父进程的数据了,这就是管道的作用过程

三、管道创建函数pipe
实际上Linux给我们提供了创建管道的函数pipe
1、pipe函数的声明
pipe函数的参数是一个输出型参数,返回两个文件描述符。管道被创建时,会需要使用两个文件描述符,一个文件描述符用于向管道写数据,一个文件描述符用于从管道读数据
pipe函数的返回值代表管道是否创建成功。如果创建成功,返回0;否则返回-1


2、pipe函数的使用
=======================步骤一:父进程创建管道=======================
int pipefd[2]; //存储创建管道时,占用的两个文件描述符
pipe(pipefd);
要使用pipe函数,需要了解pipe函数是如何跟文件描述符建立关系的,pipe函数被调用的时候,会像下面这样。当我们要从管道读数据时,使用的是文件描述符 pipefd[0];向管道写入数据时,使用的是文件描述符 pipefd[1]

注意:
为什么要使用两个文件描述符来一个读一个写,使用一个可以吗?
答案是不行!如果只有一个文件描述符来读,那么子进程继承的时候也只能读,父进程只能读,子进程也只能读,这样就无法通信
=======================步骤二:父进程创建子进程=======================
fork(); //创建子进程
我们继续创建一个子进程,让子进程和父进程通信,子进程被创建时,会继承父进程的 fd_array[ ],所以子进程也会指向这个管道

==============步骤三:关闭父进程的pipefd[1] 和 子进程的pipefd[0]=============
if(fork()==0)
{
//子进程
close(pipefd[0]);
}
//父进程
close(pipefd[1]);
管道是一个只能单向通信的通信信道,要么是父进程写,子进程读;要么是子进程写,父进程读
同时开放父进程的读写功能没有太大意义,而且容易混淆
我们这里就以 子进程写,父进程读 为例,所以我们要关闭子进程的pipefd[0],以及父进程的pipefd[1]

=======================步骤四:测试=======================
现在我们综合上述的代码,同时加一点内容来测试父子进程之间是否能通信

这里就不展示Makefile的内容了

这就说明父子间的进程就通信成功了,但是还没有结束,对于下面四种情况又该如何呢
(1) 子进程写入的速度 远大于 父进程读取的速度
(2) 子进程正在写入,但是父进程关闭了文件描述符
(3) 父进程读取的速度 远大于 子进程写入的速度
(4) 子进程写完一批数据以后关闭文件描述符,父进程在读取
这四种情况放到其他博文里说明
版权声明
本文为[abs(ln(1+NaN))]所创,转载请带上原文链接,感谢
https://blog.csdn.net/challenglistic/article/details/124279681
边栏推荐
猜你喜欢

通达OA与第三方APP对接

Connection between Tongda OA and third-party app

通达OA表单会签意见样式

Importance of slip ring technology in machine operation

神经网络 || 注意力机制的Pytorch代码实现

《ROS2机器人建模URDF》8.3动手创建一个移动机器人
![[network security] stapler1 of red team penetration project (Part 2)](/img/39/7d5594da6e7e89e510040b66eef383.png)
[network security] stapler1 of red team penetration project (Part 2)

How to install the slip ring correctly and effectively

88%工业人都不知,小程序这7点,能让营收暴增,粗暴有效!强烈建议收藏,反复读!

【Azure 应用服务】Azure Function 启用 Managed Identity后, Powershell Funciton出现 ERROR: ManagedIdentityCredential authentication failed
随机推荐
《ROS2机器人建模URDF》8.3动手创建一个移动机器人
Map&Set
尿素期货几个点涨停?尿素期货怎么做才安全?
Why is PostgreSQL about to surpass SQL Server?
《动手学机器人学》7.4机器人运动学介绍|机械臂运动学|两轮差速底盘运动学|轮式里程计
通道满了 继续往里面发 会如何?
Swift 使用AVPlayer 和 AVPlayerItem 做语音播放
项目管理系统开发成功案例
APM(应用性能监控) 行业认知系列 - 一
神经网络 || 注意力机制的Pytorch代码实现
【嵌入式】关于IAP+Xmodem从外部接收bin文件对芯片进行升级学习记录
TGIP-CN 038 报名|深度解析 Apache Pulsar 源码阅读正确姿势(一)
Circular linked list of single and double linked lists (XV)
Complete collection of basic MySQL commands
使用 Helm 部署 Wikijs
RTMP(3):Protocol Control Message
为什么:Uncaught ReferenceError: effect is not defined
Tongda OA system docking single sign on platform use and Development Manual
《ROS2机器人建模URDF》8.4控制移动机器人轮子运动
Get application instance through reflection