管道的学习
进程间通信:是指在操作系统中,两个或多个独立的进程之间进行数据交换和信息共享的一种机制
进程间通信的本质:先让不同的进程先看到同一份资源,才有通信的条件
进程间通信的目的:
1.将一个进程的数据发送给另一个进程
2.多进程之间共享同样的资源
3.一个进程需要将另一个或一组进程发送消息,通知它(他们)发生了某种事件 eg:进程终止要通知父进程
4.有些进程希望完全控制另一个进程的执行(eg:Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变
管道
管道是一种进程间通信的形式
我们把一个进程链接到另一个进程的一个数据流称为一个"管道"
匿名管道
创建一个无名管道
#include <unistd.h>
int pipe(int fd[2]);
fd:文件描述符数组
fd[0]:读端
fd[1]:写端
成功返回0,失败返回错误代码
fork共享管道
管道的使用和文件一样
管道的五种特性
1.匿名管道,只能用来进行具有血缘关系的进程进行进程间通信,所以常用于父子间
2.管道文件自带同步机制,就会有4种通信情况
3.管道是面向字节流的
4.管道是单向通信的
(属于半双工的一种特殊情况)
半双工:任何时刻,一个发,一个收
全双工:可以同时发和收
四种通信情况
1.写慢,读快 --> 读端要等写端,读端进程就会阻塞
2.写快,读慢 --> 满了的时候,写端要等读端,就要阻塞等待
3.写端关闭,读端继续 --> read就会读到返回值为0,本身文件结尾
4.读端关闭,写端继续 --> 写端再写入就没有任何意义,OS不会做没有意义的事情,就会杀掉进程,发送异常信号( 13)SIGPIPE )
命名管道
创建命名管道
int main(int argc, char *argv[])
{
mkfifo("p2", 0644);
return 0;
}
命名管道 VS 匿名管道
他们创建和打开的方式不同
匿名管道右pipe函数创建并打开
命名管道由mkfifo函数创建,打开用open
管道的写入原子性