linux--管道--父子进程之间的传输

目录

1.管道的介绍

2.pipe函数的介绍

3.pipe函数使用示例

4.验证管道的大小

5.父子进程通过管道进行交互

6.两条管道双向运输

7.mififo有名管道

7.1mififo函数介绍

7.2函数的参数说明

 7.3函数演示案例


1.管道的介绍

什么是管道,可以类比我们的这个家庭和自来水厂之间的管道,自来水负责向家庭运送水资源,我们的这个自来水厂就是写端,我们的家庭就是读端,我们可以读取这个来自于自来水厂的数据;

管道的另外一个特征就是单向流动,具体到进程上面,我们的父进程向子进程输入数据,我们的这个父进程的写端就被打开,子进程的读端就被打开;

这个里面的父进程就相当于自来水厂,子进程相当于我们的家庭,父进程打开一个写端,子进程打开一个读端即可;

2.pipe函数的介绍

pipe函数就是创建一个管道,实现任务之间的通信(interprocess commnnication);

pipefd这个数组就是调用函数之后输出的,也就是说我们调用这个函数之后数组里面就有值;

数组的内容就是管道的描述符,第一个元素就是返回的管道的读端,第二个参数返回的就是管道的写端

如果我们写进去的这个管道内容,但是我们不读取,这个时候这个管道就是阻塞的,我们的这个数据就处于一个阻塞状态,这个时候数据是存储到内核管理的缓冲区里面;

返回值:创建成功返回0,失败的话就会返回一个-1数值;

3.pipe函数使用示例

这个首先就是创建一个fd,这个fd就是一个管道,pipe调用这个参数,返回值进行判断,如果返回的是-1,说明这个函数没有调用成功,这个时候我们使用perror输出错误的原因;

因为这个管道就是实现的父进程和子进程之间的相互通信,这时候我们调用之前学习的这个fork函数创建子进程,因为这个父进程返回的是子进程的pid,所以fork返回值是pid>0的时候,这个对应的就是父进程,我们对于这个父进程,这个进行的是写的操作,因此我们需要关闭第一个参数,就是pipefd数组的第一个参数,下标是0,close就表示这个只进行写端的打开;

write对于这个进行数据的写入,ab字符串就是我们写入的内容,这个2表示的是我们写入的内容是两个字节的大小;

如果这个pid==0,说明这个就是子进程,这个时候我们就需要进行读取数据的操作,因此我们需要打开第二个参数,关闭第一个参数,fd[1]就是第二个参数,第一个参数是读取,第二个参数是写入

read就是读取这个管道的另一端写入的数据,2表示的就是两个字节大小,读取成功之后输出读取的内容;

当我们的父进程处于休眠5秒钟状态的时候,我们的这个子进程实际上就是在一直等待,直到我们的父进程休眠结束,我们的子进程接收到了数据;

4.验证管道的大小

 我们如何去验证这个管道的大小,就是我们可以一直向这个管道里面进行数据的写入么,如果不能的话,我们最多可以向这个管道里面写入多少的数据呢?

我们使用上面的代码进行判断,就是我们的子进程没写入一个*就记录一下,让这个子进程里面的循环一直进行下去,而且让创建这个子进程的父进程一直处于等待的状态;

5.父子进程通过管道进行交互

下面的这个实际上就是一个案例,通过这个案例我们想要实现数据在父子进程之间的交互;

 实现内容:我们输入的内容通过子进程写入到这个子进程里面去,我们的父进程去读取这个相关的数据 ;

这个时候,因为我们的父进程是读取数据的,子进程是写入数据的,因此这个时候子进程关闭第一个参数,父进程关闭第二个参数,我们的父进程负责从管道里面读取我们在键盘上面输入的内容;

6.两条管道双向运输

我们的这个双向运输想要使用下面的这个案例进行介绍:首先说明一下这个案例实现的目的,就是我们的这个父进程写入数据,子进程接收到数据之后把这个数据全部转换为大写的,然后这个子进程通过另外一个管道把这个转换之后的大写的数据传输给我们的父进程,这个就是一个双向的运输的管道的过程;

输入数据的过程:这个里面的fd就是父进程,fd2就是子进程,我们的这个第一次传输的时候父进程写入数据,因此我们需要关闭这个父进程的第一个参数,就是读取的参数;

就是我们的一个管道的读取数据,写入到另外一个管道里面去,这个题目里面,就是父进程读取书,写到子进程这个里面去,因此,我们的父进程的写管道关闭,就是第二个参数,子进程的读取管道关闭,只需要被写入数据,也就是只需要保留第二个参数,因此我们把第一个参数关闭即可;

转换后的数据再次传递回去的过程:这个其实就是和上面进行的相反的操作,首先,我们上面的这个过程进行的时候,对于这个父进程,因为是要读取数据,写入到这个子进程里面去,因此是把这个父进程的写管道关闭了,子进程的读管道关闭了;

但是在这个问题里面,我们的这个是子进程把这个父进程的字符全部转换为大写的之后传递给这个父进程,因此这个时候相当于是这个子进程给出数据,写入到这个父进程里面去,我们的这个close里面的这个参数正好是和上面的相反的;

write这个函数的fd[1]针对的就是父进程的这边,就是这个转换后的这个大写的情况全部写入到这个父进程,因此这个时候父进程的fd[1]是被使用的,写入的这个内容的多少就是使用的这个sizeof进行计算的;

对于这个子进程,就是读取数据放到这个管道里面去,因此这个read函数的第一个参数就是这个fd2(子进程管道)的读取端,读取的内容大小也是使用的这个sizeof进行计算的;

7.mififo有名管道

为什么会有这个有名管道,他的这个背景是什么,就是因为我们上面使用的这个pipe函数创建的管道属于无名的管道,这个是局限于这个亲缘关系的这个进程之间才可以使用,例如这个父子进程,兄弟进程之类的,对于这种有亲缘关系的进程,我们可以使用这个pipe函数创建的无名的管道,但是对于没有关系的两个进程,我们这个时候只能使用这个mififo函数创建有名管道进行信息的传递

7.1mififo函数介绍

这个函数的参数就是:文件路径,以及这个编码mode,我们在后面的这个使用中具体介绍;

7.2函数的参数说明

mkfifo函数创建的这个有名的管道本质上就是一个文件,毕竟这个linux下面一切皆文件,mode这个参数表示的就是这个文件的一个权限,也就是这个有名管道的一个权限,这个涉及到这个所属组等相关的概念,我们这个地方不详细介绍,可以自行系统学习,简单的讲,就是每一个都包含3个权限,读写权限之类的,使用数字进行表示;我们后面编写的这个函数使用666进行代替,这个里面的每一个6代表的都是一个具体的实际意义;

 7.3函数演示案例

当我们的这个有名管道里面没有任何内容的时候,我们的进程想要从这个里面去读取数据,这个时候的这个进程就会处于一个阻塞的状态,直到有另外一个进程向这个里面写入一些内容,否则这个读取内容的进程就会一直处于阻塞的状态;

正常创建成功的时候,这个返回值就应该是0,当这个返回值不是0的时候,就说明这个函数的调用出现了问题,我们的这个时候有名管道里面没有内容,因此这个时候,我们的这个进程处于阻塞的状态,我们的read就是想要从这个管道里面读取数据,把这个读取的数据存储到这个buiff数组里面去;

我们这个下面的代码就是一个进程向这个管道里面写入一些内容,使用的是有参数的main函数,把这个写的buf内容发送到这个管道里面去;

我们如何运行呢,下面的这个.write就是这个写内容的生成的可执行程序,我们向这个管道里面写入这个hello 之前这个上一个进程读取这个数据,因为这个有名管道里面没有数据,因此这个就会一直处于等待的阻塞状态,所以这个时候我们这边一点写入数据,那边的阻塞状态就会结束,把我们写入的数据读取到,从而结束进程;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值