前言: 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.需使用两个系统调用(上图标注1和2),1中的系统调用为操作系统提供的一种机制(linux提供了 select和poll两中实现),称为复用器。 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操作的功能实现逐步移至系统层,避免用户层到系统层上下文的切换。 |
|