title: "IPC管道"
date: 2019-10-8
categories: linux
tags: C C++ linux
IPC管道
概述:
不管是有名管道,还是无名管道,它们的本质其实都是一样的,它们都是内核所开辟的一段缓存空间。进程间通过管道通信时,本质上就是通过共享操作这段缓存来实现,只不过操作这段缓存的方式,是以读写文件的形式来操作的。
半双工管道,即,读和写操作是分开进行的。
- 不能在共享文件夹下调试,window的文件系统不支持管道文件,把创建的管道文件路径设为linux的本地文件夹!!!!!!!
特质:
-
其本质是一个伪文件(实为内核缓冲区)
-
由两个文件描述符引用,一个表示读端,一个表示写端。
-
规定数据从管道的写端流入管道,从读端流出。
无名管道:
- 无名管道(PIPE):只有创建该管道的程序,才能够找到该管道(亲缘进程通信)
- 单向传输
- 控制进程只有pipe的一端
- pipe的阻塞操作
fd[0] 读 fd[1]写
SIGPIPE - 无名管道的内核资源在通信两进程退出后会自动释放,不能像普通文件一样存储信息,不能使用lseek来修改当前pipe的使用位置
- 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
- read write 返回-1 读端close 会收到SIGPIPE信号
函数:
int pipe1_fd[2] = {-1,-1};
if(pipe(pipe1_fd) < 0) //创建管道
{
printf("pipe1 error, %s\n",strerror(errno));
return 1;
}
有名管道:
- FIFO 是依赖于文件系统,
依赖于文件系统,像普通文件一样具有磁盘路径,文件权限和其他属性,所有程序都可以通过path找到有名管道
-
FIFO 是一个设备文件,存储信息在内存,当两个进程都消失,数据消息,文件只有接口的作用
-
单项通信
-
只能够进行少量数据传输
-
只能一对一进行传输
-
两个进程,中途退出了一个进程,未退出的一端如果是写操作的话,返回sigpipe信号
-
未退出的一端如果是阻塞读操作的话,该读操作不会继续阻塞,直接返回0
-
调用open打开有名管道的进程可能会被阻塞。但如果同时用读写方式(O_RDWR)打开,则一定不会导致阻塞;
以只读方式(O_RDONLY)打开,则调用open函数的进程将会被阻塞直到有写方式打开管道;
以写方式(O_WRONLY)打开也会阻塞直到有读方式打开管道。
-
有名管道是一个存在于硬盘上的文件,即映射到文件系统,而管道是只存在于内存中的特殊文件。
函数:
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char* pathname, mode_t mode);
mkfifo(FIFO_NAME, S_IFIFO|0666); //FIFO_NAME必须不存在
mkfifo ()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此 umask值也会影响到FIFO文件的权限。
参数:
mode S_IFIFO|0666 指明创建一个有名管道且存取权限为0666