系统的几种IO模型

前言:

  1.在计算机系统中,操作系统充当着IO操作等这个硬件相关的功能具体实现的基本角色之一。而我们所开

   发应用程序中所涉及到硬件相关的操作时,本质上是通过调用操作系统给我们提供的函数来实现的。

   

  2.概念介绍

   用户态和系统态:

     用户态:当cpu执行的指令处在用户层时,此时程序处于用户态。

     系统态:当cpu执行的指令处在系统层时,此时程序处于系统态。

   阻塞和非阻塞:

     阻塞:某个事件执行过程中,发出执行操作的请求,而该请求操作需要的条件不满足,那么就会一

         直在那等待,直至条件满足。在IO操作中即为系统调用发起到IO执行开始这一段过程。

     非阻塞:当某个事件执行过程中,发出执行操作的请求,而该请求操作需要的条件不满足,会立即

          返回一个标志信息告知条件不满足,发起者就不会一直在那等待。在IO操作中即为系统调用

          发起,若不满足执行IO操作时,系统层向用户层返回信息,用户层就不会等待。    

   同步和异步:

     同步:某个事件的发生,就必须逐个顺序地进行,从而会导致整个流程的暂时等待,事件外的事件

         没有办法并发地执行。在IO操作中表现为当IO操作发生时,用户层的其他流程无法执行(站在

         用户层程序的角度看,IO操作发生时,我程序的其他部分无法执行了)

     异步:某个事件的发生,不会导致整个流程的暂时等待,事件外的事件可以并发地执行。IO操作

         中表现为当IO操作发生时,用户层的其他流程照样执行(在用户层程序来看)。

   IO操作主要流程:

     1.用户程序调用系统IO函数。

     2.系统等待数据就绪。

     3.IO数据由系统内存空间拷贝到用户内存空间。

     4.用户程序操作IO函数调用返回的数据。

操作系统IO模型:

   1.目前操作系统的IO模型有5中:阻塞IO/非阻塞IO/IO复用/事件驱动IO/异步IO

   1.1.阻塞式IO
      

     第一阶段是指磁盘把数据装载到内核的内存中空间中。

     第二阶段是指内核的内存空间的数据copy到用户的内存空间(这个才是真实I/O操作)。

   1.2.非阻塞式IO

     
       

     每隔一段时间,询问系统数据是否准备完成,在用户层上则表现为需不断while循环调用询问数据是

     否就绪。

   1.3.IO复用

      
        

      1.需使用两个系统调用(上图标注12)1中的系统调用为操作系统提供的一种机制(linux提供了

       selectpoll两中实现),称为复用器。

      2.IO复用流程介绍:a)select/poll机制主要功能时帮助调用者寻找在其上注册过切就绪的设备(

                   是非阻塞IO中将由用户层来判断是否数据已就绪的功能交给系统来做,并且

                   可判断多个IO设备),用户层程序调用后会被阻塞。

                  b)当有设备数据就绪时,通知调用者。

                  c)调用者即可进行IO数据的系统调用

      3.好处:只需启动一个线程不断去轮询复用器上注册IO设备的状态即可,避免了一个线程对应一

           个IO设备的情况,减少了资源占用。

   1.4.事件驱动IO

      
        

      1.采用回调的方式,给相应IO设备事件注册事件处理函数,用户层程序继续往下执行由系统来关

        注数据是否就绪,并通过发生信号来通知用户层程序来调用事件处理函数。

      2.好处:等待数据准备好这段时间,用户层程序不会处于阻塞状态中。

      3.如果一个事件通知一个进程,进程正在忙的,提供一下两种机制处理

       水平触发机制: 内核通知进程来读取数据,进程没来读取数据,内核需要一次一次的通知进程。

       边缘触发机制: 内核只通知一次让进程来取数据,进程在超时时间内,随时可以来取数据,把这个事

                 件信息状态发给进程,好比发个短息给进程( nginx默认采用了该机制)。

    1.5.异步IO

      
       

                  1.不同于以上的IO模型,当IO数据就绪后,也是由系统负责将数据拷贝到用户层中,再通过信号

        通知用户层程序后,用户层程序就直接可以操作IO调用后返回的数据了(用户层程序无需发起读

        取数据的系统调用了)。

总结:

    1.我们可以看出IO操作的功能实现逐步移至系统层,避免用户层到系统层上下文的切换。

猜你喜欢

转载自javazqd110.iteye.com/blog/2347227
今日推荐