unix内核源码剖析【11. 管道】

一、参考

Unix内核源码剖析

二、什么是管道

管道是在父进程和子进程之间通信的机制,因为进程拥有各自独立的虚拟地址空间,所
以任意进程无法直接访问其他进程拥有的数据。为了实现进程间的通信,设计了管道。

管道对文件系统的一部分进行了巧妙的应用,使得进程间的通信成为可能,管道首先获取根磁盘的inode, 然后利用该inode指向的存储区进行数据交换。这个文件(inode和存储区域)构成了管道的实体。管道的容量由PIPSIZE定义于ken/pipe.c

image.png

利用管道进行的通信过程如下:
(1)发送发的进程向管道写入数据,直到管道被充满;
(2)切换到接收方的进程,使得从管道读入数据,已经接收的数据从管道中被删除;
(3)数据全部读取后,切换到发送发的进程,返回(1)的处理

发送方以与管道相对应的inode[]元素的地址+1, 接收方以该地址+2为参数执行sleep()

image.png

使用管道的优点:

在进程间传递数据也可以通过临时文件来实现,与临时文件相比,使用管道的优点:
(1)可使用的块设备的资源是有限的,管道的容量为固定的4096字节,因此,即使用来交换更大容量的数据也不会占用更多的块设备区域,而使用临时文件时候,会占用与所交换的数据相等容量的块设备区域
(2)管道所需要的缓冲区的容量小于缓冲区的总容量,利于发挥块设备缓冲区的缓存功能,而且,当发送方的进程将数据写入管道后,接收方的进程将马上进行读取,块设备的缓存效果会更加明显,当使用临时文件时候,如果需要输出大于设备缓冲区容量的文件,缓冲区所带来的缓存效果将因此受到影响;
但是,当使用管道,且执行进程由发送方切换到接收方时候,如果存在执行优先级更高的进程,且该进程也使用了块设备的缓冲区的时候,则无法期待缓冲区带来的缓存效果。此时,虽然性能没有得到改善,但是由于数据已经输出到块设备,因此对通信内容本身不会造成影响。

管道基于现有的文件系统,实现的成本较低,尽管占用的资源较少,但是却实现了进程之间的高速通信,低投入高产出可以视为管道最大的魅力。

三、开始管道通信

系统调用pipe用来建立管道通信,pipe()是系统调用的处理函数

image.png

首先在user.u_ofile[]file[]中分配供readwrite使用的元素,然后获取根磁盘的inode[]元素,将供readwrite使用的file[]元素指向该inode[]元素,为file[]元素设置表示管道的FPIPE标志位

image.png

readwrite使用的文件描述符返还给用户程序,用户程序对该文件描述符,可以像对待一般文件一样进行读写,实现管道通信。

四、收发数据

对通过系统调用pipe取得的文件描述符,可以像对待一般文件那样执行系统调用readwrite,从而实现数据收发

image.png

当设置了file[]元素的FPIPE标志位时候,在rdwr()方法中执行writep()readp()方法

4.1 writep

writep()用于对管道进行写入处理,因为管道的实体为文件,所以采用与对待一般文件相同的方式调用writei()写入数据,当管道被充满(4096字节)时候进入睡眠状态,如果存在等待管道被写入数据的进程,则将其唤醒;但是,和一般文件处理不同,文件偏移量file.f_offset不会发生变化

五、结束管道通信

你可能感兴趣的:(管道,fork,unix)