1、无名管道
理解无名管道其实很简单,把下面这几种情况搞懂了,无名管道的使用就会了
(1)非阻塞读无名管道,如果没有进程可以访问写端,读操作都将立即返回
如果管道无数据,立即返回0
如果管道现有数据大于要读出的数据,立即读出要读取大小的数据
如果管道现有数据小于要读出的数据,立即读出现有数据
(2)阻塞读无名管道,如果有进程可以访问写端
如果管道无数据,读操作阻塞
如果管道现有数据大于要读出的数据,立即读出要读取大小的数据
如果管道现有数据小于要读出的数据,立即读出现有数据
(3)写无名管道,如果没有进程可以访问读端,写操作都将收到SIGPIPE信号,write函数返回-1
(4)写无名管道,如果有进程可以访问读端,且管道有空间,则写入成功,如果管道已满,则阻塞当前进程
2、重定向
每个进程都有三个流
stdin 0 标准输入
stdout 1 标准输出
stderr 2 标准错误输出
重定向就是操作输入/输出流
1、cat<tes1
将标准输入重定向到tes1,实际为:cat 1<tes1
2、cat>tes1<tes2
将标准输出重定向到tes1,标准输入重定向到tes2,实际为:cat 1>tes1 0<tes2
如果tes1文件存在的话,会覆盖文件内容,如果需要追加内容则应使用cat>>tes1<tes2
3、cat>tes1 2>tes3 <tes1
将标准输出重定向到tes1,标准输入重定向到tes2,标准错误输出重定向到tes3,实际为:cat 1>tes1 2>tes3 0<tes1
4、cat>tes1 2>&1<tes2
将标准输出重定向到tes1,标准输入重定向到tes2,2和1联合,因此标准错误输出也将输出到tes1。
5、cat 2>&1 >tes1<tes2
先将2和1联合,再将标准输出重定向到tes1,标准输入重定向到tes2,但是这个不同的是,2和1一开始是输出到当前终端,联合后还是输出到当前终端,联合没有传递性,再将1重定向的话,那么标准输出会输出到tes1,而标准错误输出依旧为当前终端
3、有名管道
有名管道和无名管道也是类似的
1、如果以写的方式打开管道,则需要另一个进程以读的方式打开。即如果以某种方式打开有名管道,则系统将阻塞进程,直到另一个进程以另一种方式打开该管道。
2、两进程已经完成打开管道操作,阻塞读
如果管道中没有数据,读默认阻塞
如果有数据,但大于读取量,则读取期望大小数据
如果有数据,但小于读取量,则读出所有数据
3、两进程已经完成打开管道操作,阻塞写
如果管道中没有空间,写阻塞
如果有空间,且空间大于写入数据,则写入数据后返回
如果有空间,但空间小于写入数据,则写入数据后阻塞
4、两进程已经完成打开管道操作,中途一个进程退出
未退出的一端是写操作,将返回SIGPIPE信号
未退出的一段是阻塞读操作,读操作将不阻塞,直接返回0
4、总结
1、管道是特殊类型的文件,在满足先入先出的原则条件下才能进行读写,但不能定位读写位置
2、管道是单向的,无名管道一般只用于亲缘关系进程间通信,而有名管道以磁盘文件的方式存在,可以实现本机任意两进程间通信
3、无名管道创建时直接返回文件描述符,但是在读写时需要确定对方的存在,即阻塞于读写位置,而有名管道再打开时需要确定对方的存在,否则阻塞