父子进程间通信(一) —— 匿名管道的创建和使用

进程之间可能存在协同工作的场景,一个进程把自己的数据交付给另一个进程,让其进行处理,如:

cat file.txt | wc -l

执行cat指令会触发一个进程,执行完cat file.txt 能读取到file.txt文件的内容,然后将读取结果通过管道交付给下一个进程wc,让wc来统计file.txt文件有多少行内容

这就是进程间通信的方式之一 —— 管道


目录

一、进程间通信的本质前提

二、管道的作用原理

 三、管道创建函数pipe

1、pipe函数的声明

2、pipe函数的使用


一、进程间通信的本质前提

因为进程之间具有独立性,一个进程是看不到另一个进程的资源的!!

两者在这种水火不容的情况下,要如何进行通信呢?? 答案是 给他们一块公共资源(公共内存)

这块内存不属于任何进程!!如果属于进程A,那么进程B能访问到这块公共资源,这就打破了进程的独立性原则,所以这块公共资源属于OS

 所以进程间通信的前提就是 有一块双方都能访问的公共资源,这块资源是属于OS的

二、匿名管道的作用原理

下面以父子进程为例,介绍管理的作用方式

一个进程如果要向磁盘写入数据,那么必会先得到写入文件的文件描述符fd ——》 找到对应文件的struct file ——》 调用文件操作函数 ——》向文件内核缓冲区写入数据 ——》OS定时调用驱动函数 write_disk 向磁盘写入数据

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

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

 三、管道创建函数pipe

实际上Linux给我们提供了创建管道的函数pipe,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))的博客-CSDN博客https://blog.csdn.net/challenglistic/article/details/124325409?spm=1001.2014.3001.5501

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值