IO模型介绍

先理解几个问题:

(1)为何读取文件的时候,须要用户进程经过系统调用内核完成(系统不能本身调用内核)什么是用户态和内核态?为何要区份内核态和用户态呢? 

  在 CPU 的全部指令中,有些指令是很是危险的,若是错用,将致使系统崩溃,好比清内存、设置时钟等。若是容许全部的程序均可以使用这些指令,那么系统崩溃的几率将大大增长。因此,CPU 将指令分为特权指令和非特权指令,对于那些危险的指令,只容许操做系统及其相关模块使用,普通应用程序只能使用那些不会形成灾难的指令。linux

  当进程运行在内核空间时就处于内核态,而进程运行在用户空间时则处于用户态。windows

  在内核态下,进程运行在内核地址空间中,此时 CPU 能够执行任何指令。运行的代码也不受任何的限制,能够自由地访问任何有效地址,也能够直接进行端口的访问。
  在用户态下,进程运行在用户地址空间中,被执行的代码要受到 CPU 的诸多检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段(TSS)中 I/O 许可位图(I/O Permission Bitmap)中规定的可访问端口进行直接访问。服务器

  对于 Linux 来讲,经过区份内核空间和用户空间的设计,隔离了操做系统代码(操做系统的代码要比应用程序的代码健壮不少)与应用程序代码。即使是单个应用程序出现错误也不会影响到操做系统的稳定性,这样其它的程序还能够正常的运行(Linux 但是个多任务系统啊!)。网络

  因此,区份内核空间和用户空间本质上是要提升操做系统的稳定性及可用性。并发

  

如何从用户空间进入内核空间?
  咱们能够经过内核提供的接口来完成这样的任务。好比应用程序要读取磁盘上的一个文件,它能够向内核发起一个 "系统调用" 告诉内核:"我要读取磁盘上的某某文件"。其实就是经过一个特殊的指令让进程从用户态进入到内核态(到了内核空间),在内核空间中,CPU 能够执行任何的指令,固然也包括从磁盘上读取数据。具体过程是先把数据读取到内核空间中,而后再把数据拷贝到用户空间并从内核态切换到用户态。此时应用程序已经从系统调用中返回而且拿到了想要的数据,能够开开心心的往下执行了。简单说就是应用程序把高科技的事情(从磁盘读取文件)外包给了系统内核,系统内核作这些事情既专业又高效。

每一个处理器在任何指定时间点上的活动归纳为下列三者之一:框架

  • 运行于用户空间,执行用户进程。
  • 运行于内核空间,处于进程上下文,表明某个特定的进程执行。
  • 运行于内核空间,处于中断上下文,与任何进程无关,处理某个特定的中断。

以上三点几乎包括全部的状况,好比当 CPU 空闲时,内核就运行一个空进程,处于进程上下文,但运行在内核空间。异步

 

那么什么样的操做只能运行在内核态呢? 
  •  用户态:只能受限的访问内存,没法访问外围设备。 
  • 内核态:能够访问内存全部数据 

  一些对外围设备的访问操做好比硬盘、网卡都只能运行在内核态,此外进程调度、TCP/IP协议栈等也只能工做在内核态。socket

(2)文件描述符(fd)  

  文件描述符是一个非负整数,实际上,他是一个索引值,指向内核为每个进程所维护的该进程打开文件的记录表,当程序打开一个现有文件或者建立一个新文件时,内核向进程返回一个文件描述符。当咱们的进程想要对文件进行读写的时候,就会传递这个文件描述符给内核空间,内核就会根据不一样类型的IO对相应的数据进行操做返回。 用户进程若是想要从外围设备(这里以socket为例)读取数据,须要首先通过内核,那这里就涉及到和内核的通讯问题了。

高并发

各个IO模型介绍

(1)阻塞IO 

  好比说网络io,当咱们须要去获取一个网页的数据返回的时候,若是服务器无返回的时候,就会一直阻塞等待数据返回。这样cpu的浪费就很严重。编码

 

(2)非阻塞IO 

 

  用户进程想要读取数据了,因而就经过执行recvfrom来进行一次系统调用,进入内核态,内核态若是数据没有准备好就直接返回一个没有准备好的标志,咱们这边的用户进程也没有闲着,就去干别的事了,(可是后面的执行须要用到数据的话,那么仍是要等待数据返回)可是仍是会定时轮询系统调用查看数据是否准备好

(3)IO 复用

 

  前面的前面两种方式一个进程只能监听一个返回状态,但select能够同时监听多个返回状态,好比同时发起100个socket,一旦有一个数据返回了就去当即处理。因此说效率大大提升了。可是将数据从内核复制到用户控件这个时间仍是有浪费。

 

(4)真正的异步IO 

  获得数据以后,操做系统会将数据从内核复制到用户空间以后,再给信号处理程序发起数据。少了中间拷贝数据的过程,是操做系统准备好了以后再发给用户进程的。异步io在io复用的基础上没有太大的提高, 可是编码难度复杂,因此现在不少程序的框架仍是普遍使用的仍是io复用。

select

poll

epoll(linux下支持,windows不支持) 运用红黑树查询,效率很高

  

  分析:epoll不必定就比select好,

  •  高并发,可是链接活跃度不高的状况下,epoll优于select(好比浏览网页,用户的链接时间可能不长)
  • 并发不高,同时活跃度很高的状况下,select优于epoll (好比游戏,链接上了不会一会儿断开又链接)
相关文章
相关标签/搜索