系统IO模型

web服务器

一、系统IO模型

1.一、消息通讯机制

一、同步和异步
  同步:进程发出请求调用后,进程会一直处于等待状态,直到内核返回响应消息之后才能进行下一步操做,若是内核一直不返回数据,那么进程就会一直等待内核响应消息。
  异步:进程发出请求调用后,进程无需等待内核返回响应消息,会进行其余的操做或者发送下一个调用请求。
  阻塞:IO操做须要完全完成后才返回到用户空间,调用结果返回以前,调用者被挂起,没法进行其余操做,调用者只有在获得结果以后才会返回,该线程在此过程当中不能进行其余处理。
  非阻塞:IO操做被调用后当即返回给用户一个状态,无需等到IO操做完全完成,最终的调用结果返回以前,调用者不会被挂起,能够去作别的事情。
nginx

1.二、同步阻塞型IO

  阻塞IO模型是最简单的IO模型,用户线程在内核进行IO操做师被阻塞,用户线程经过系统调用read发起IO操做,由用户空间转到内核空间。内核等到数据包到达后,而后将接收的数据cp到用户空间,完成read操做,用户空间须要等待read将数据读取到buffer后,才继续处理接受的数据。整个IO请求的过程当中,用户线程是被阻塞的,这致使用户在发起IO请求时,不能作任何事情,对CPU的资源利用率不够。
  优势:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用CPU资源
  缺点:每一个链接须要独立的进程/线程单独处理,这样虽然能够有效的利用CPU资源,可是代价就是多进程的大量内存开销。
  同步阻塞:程序向内核发送IO请求后一直等待内核响应,若是内核处理请求的IO操做不能当即返回,则进程将一直等待并再也不接收新的请求,并由进程轮询查看IO是否完成,完成后进程将IO结果返回给Client,在IO没有返回期间进程不能接收其余用户的请求,并且只有进程本身去查看IO是否完成。
web

 1.三、同步非阻塞IO

  在同步阻塞IO中,进程实际等待的时间可能包含两部分,一个是等待数据的就绪,另外一个是等待数据的复制;与此不一样的是,同步非阻塞IO的调用不会等待数据的就绪,若是数据不可读或者不可写,它会当即告诉进程。相比于阻塞IO,非阻塞IO结合反复轮询来尝试数据是否就绪,防止进程被阻塞,最大的好处便在于能够在一个进程里同时处理多个IO操做。因为须要进程执行屡次的轮询来查看数据是否就绪,这样花费了大量的CPU时间,使得进程处于忙碌等待状态。数组

 1.四、多路IO复用

  在实际应用中,特别是在web服务器,同时处理大量的文件描述符是必不可少的(高并发),这时使用同步非阻塞IO显然不是合理的;由于服务器想要同时接受多个TCP链接的数据,就必须轮流对每一个socket调用接收数据的 方法。无论这些socket有没有能够接收的数据,都要询问一遍,那么假如大部分socket并无数据能够接收,那么就会浪费不少CPU时间用于检查这些socket。多路IO复用就绪通知,就提供了对大量文件描述符就绪检查的高性能方案,它容许进程经过一种方法同时监听全部的文件描述符,并能够快速得到全部就绪的文件描述符,而后只针对这些描述符进行数据访问。服务器

  select模型:select模型经过一个select()系统调用来监视包含多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程能够得到这些文件描述符从而进行读写操做。select的一个缺点是单个进程可以监听的文件描述符的数量存在最大限制(Linux上通常为1024),因此加入使用select的服务器最多只能同时监听1024(64位操做系统默认为2048)个链接。因为nginx的prefork模型其底层所使用的的是select模型,所以nginx的prefork的最大链接数为1024。其次,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增加;因为网络响应时间的延迟使得大量的TCP链接处于非活跃状态,但调用select()会对全部socket进行一次线性扫描,因此在必定程度上浪费CPU时间。网络

相关文章
相关标签/搜索