IPC(进程间通信)之管道详解

linux和windows中都有

管道和共享内存(最快的IPC)区别:

1.管道一次通信四次数据拷贝:由用户空间的buf中将数据拷贝到内核中->内核将数据拷贝到内存中->内存到内核->内核到用户空间的buf。而共享内存则只拷贝两次数据:用户空间到内存 -> 内存到用户空间。

2.管道用循环队列实现,连续传送数据可以不限大小。共享内存每次传递数据大小是固定的;

3.共享内存可以随机访问,管道只能顺序读写;

 

匿名管道

在具有公共祖先的进程之间进行通信。通信跟随进程消亡,所以是只存在于内存的临时文件由于这种文件没有文件名,不能被非亲进程所打开,只能用于亲属进程间的通信,所以这种没有名称的文件形成的通信管道叫做“匿名管道”。

 

原理:创建子进程会复制父进程包括文件在内的一些资源。如果父进程创建子进程之前创建了一个文件,那么这个文件的描述符就会被之后创建的子进程所共享,父、子进程可以通过这个文件进行通信。如果通信的双方一方只能进行读操作,而另一方只能进行写操作,那么这个文件就是一个只能单方向传送消息的管道。

 

实现:进程通过调用函数pipe()创建一个管道。pipe()函数的功能就是创建一个内存文件,但与创建普通文件的函数不同,函数pipe()将为进程返回这个文件的两个文件描述符。其中,一个只读属性的文件描述符,一个只写属性的文件描述符,即进程通过fildes[0]只能进行文件的读操作,而通过fildes[1]只能进行文件的写操作。确定传输方向后,一方关闭fildes[0],一方关闭(close())文件描述符fildes[1],于是管道的连接情况就变成如下情况的单向传输管道。

 

IPC(进程间通信)之管道详解

父进程创建管道

IPC(进程间通信)之管道详解

父进程创建子进程后,管道也被共享

IPC(进程间通信)之管道详解

通信一方关闭读,一方关闭写。方法:close()文件描述符

局限性:建立在内存中,所以它的容量不可能很大;传送的是无格式字节流,要求使用管道的双方实现必须对传输的数据格式进行约定。

 

 

命名管道

在实际文件系统上真正的文件,所以它可以在任意进程之间实现通信。

由于命名管道严格遵守先进先出的原则进行传输数据,所以这种管道也叫做FIFO文件

由于需要由管道自身来保证通信进程间的同步,命名管道也是一个只能单方向访问的文件。

原理:也就是说,命名管道提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,在文件系统中产生一个物理文件,其他进程只要访问该文件路径,就能彼此通过管道通信。在读数据端以只读方式打开管道文件,在写数据端以只写方式打开管道文件。

与普通文件的区别:

普通文件无法实现字节流方式管理,多进程访问资源冲突;
FIFO文件采用字节流方式管理,遵循先入先出原则,不涉及共享资源访问。
操作流程为:mkfifo -> open -> read(write) -> close ->unlink。