linux 文件I/O原理及模型

linux 文件I/O原理及模型

 
   

   我们知道Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设备的操作都可以看做对文件进行操作。我们对一个文件的读写,都通过调用内核提供的系统调用;内核给我们返回一个file descriptor(简称:fd,文件描述符);我们通过 ls -l  /proc/${pid}/fd/ 可以看到进程${pid}占用的所有描述符,或者lsof -p ${pid}; 而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符);描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性); 那么我们的应用程序对文件的读写就通过对描述符的读写完成。

 

 

     系统调用是如何完成一个I/O操作的呢? linux将内存分为内核区,用户区; linux内核给我们管理所有的硬件资源,应用程序通过调用系统调用和内核交互,达到使用硬件资源的目的;应用程序通过系统调用read发起一个读操作;这时候内核创建一个文件描述符,并通过驱动程序向硬件发送读指令,并将读的的数据放在这个描述符对应结构体的缓存区。但这个结构体是在内核内存区的。需要将这个数据读到用户区。这样完成了一次读操作;

 

 

     但是大家都知道I/O设备相比cpu的速度是极慢的。linux提供的read系统调用,也是一个阻塞函数。这样我们的应用进程在发起read系统调用时,就必须阻塞,就进程被挂起而等待文件描述符的读就绪;

 

 

      这里,我们先了解一下,什么是文件描述符读就绪,什么是写就绪?

 

 

       读就绪:就是这个文件描述符的接收缓冲区中的数据字节数大于等于套接字接收缓冲区低水位标记的当前大小;

       写就绪:该描述符发送缓冲区的可用空间字节数大于等于描述符发送缓冲区低水位标记的当前大小。(如果是socket fd,说明上一个数据已经发送完成)。

 

      接收低水位标记和发送低水位标记:由应用程序指定,比如应用程序指定接收低水位为64个字节。那么接收缓冲区有64个字节,才算fd读就绪;

 

 

 

    从上边的分析我们知道向内核发起一个I/O操作,要经过等待fd就绪+内核数据到用户数据区复制,完成一次I/O。

 

 

 

各种I/O模型比较

 

 

 

1、阻塞I/O:进程被阻塞I/O系统调用上(read、write、sendto、recvfrom等等)直到I/O条件就绪(可读/写或异常)处理完,处理后从I/O系统调用返回进程。

 linux <wbr>文件I/O原理及模型

初始化操作后,一直阻塞,直到操作完成。如:读数据,则其他线程无法要读数据是,被阻塞,等到该读线程完成后,其他的线程才能进行读操作。

2、非阻塞I/O :这种方式通过指定系统调用read/write的参数为非阻塞,告知内核fd没就绪时,不阻塞进程,而是返回一个错误码,这时应该使应用进程死循环轮询,直到fd就绪;。

 linux <wbr>文件I/O原理及模型
强调一种主动性,即程序主动去轮询可以操作了吗?系统就响应它。如:读数据,它会想询问内核,线程:可以读了吗?内核:不行。线程:可以读了吗?内核:不行。……


 

3、I/O复用( I/O 多路转接模型):在这种模型下,如果请求的 I/O 操作阻塞,且它不是真正阻塞 I/O,而是让其中的一个函数等待,在这期间,I/O 还能进行其他操作。如本节要介绍的 select 函数和 poll 函数,就是属于这种模型。

linux <wbr>文件I/O原理及模型

4、多线程阻塞I/O。把要处理的描数字分配到多个线程中,每个线程独立地调用I/O系统调用,独立处理。

 

5、信号驱动I/O。类似于I/O复用,当I/O条件就绪时使用信号通知进程去调用I/O系统调用处理。

 

6、异步I/O。通过aio_read告诉内核怎么处理,我们就不管了,内核处理完了后发个信号告诉我们,也可以用其他方式在处理完通知我们。

linux <wbr>文件I/O原理及模型

 

注:I/O系统调用是否阻塞,仅取决于他们操作的描数字是否是阻塞的。fcntl可设定。

对普通文件的读写不存在阻塞问题,对和终端、网络连接等对应的文件描述符才会阻塞

阻塞操作是指,在执行设备操作时,若不能获得资源,则进程挂起直到满足可操作的条件再进行操作。非阻塞操作的进程在不能进行设备操作时,并不挂起。被挂起的进程进入sleep状态,被从调度器的运行队列移走,直到等待的条件被满足。

 

 

 

这6种I/O模型分为2类:

 

同步I/O模型:第1~5 I/O模型。这5种I/O模型,说到底,I/O调用还是要用户进程自己调用,被阻塞。

 

异步I/O模型:第6种I/O模型。I/O调用由内核执行,进程不被阻塞。

 

 

 

注:鉴别是否是异步I/O操作,只要看I/O操作是谁执行。

猜你喜欢

转载自tcxiang.iteye.com/blog/2284905