内容目录

IO基本概述

什么是IO

  • 所谓IO,无非就是输入输出,其实大家更多关注的是磁盘IO,事实上当我们在网络中传送一些数据时,本质上也是一种IO

什么是网络IO

  • 拿用户请求Nginx这样的web服务器获取磁盘中的文件时,系统是如何处理的?

file

  • 通过上面的例子,用户每一次请求都会发生一次IO操作:而每次IO,都要经由两个阶段:
    • 第一步:将数据从磁盘加载至内核的内存空间(缓冲区),等待数据准备完成,时间较长
    • 第二步:将数据从内核缓冲区复制到用户空间的进程内存(缓冲区),时间较短
    • 第三步:Nginx封装数据为响应报文发送
  • nginx下发指令给内核后,nginx是等待,还是不等待继续处理新的请求
  • 数据拷贝到内核缓冲区了,通知nginx应用程序,阻塞

IO网络模型

  • IO模型分为同步、异步、阻塞、非阻塞

同步/异步

  • 同步/异步(关注的是消息通知机制)
  • 同步:调用者发指令给被调用者,被调用者需要获取资源后再返回给调用者,那么此时调用者需要时不时去看一下,对于调用者来说很繁忙。
  • 异步:调用者发指令给被调用者,被调用者需要获取资源后再返回给调用者,此时被调用者会主动将当前的运行状态通知给调用者。

阻塞/非阻塞

  • 阻塞/非阻塞(关注的是调用者在等待被调用者返回结果之前所处的状态)
  • 阻塞:指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起
  • 非阻塞:指IO操作被调用后立即返回给用户进程一个状态值,无需等待IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起

IO组合模型

  • 同步阻塞:将衣服扔到洗衣机,然后守在洗衣机旁边,等待什么时候洗完什么时候处理
  • 同步非阻塞:将衣服扔到洗衣机,然后可以去干别的事情,是否洗完不知道,需要时不时看一下
  • 异步阻塞:将衣服扔给洗衣机,还是会在旁边等着(阻塞),洗衣机洗完了会通知
  • 异步非阻塞:将衣服扔给洗衣机,可以去干其他事情,等待洗衣机洗完了会通知,然后再去取衣服

五种常见IO模型

同步阻塞IO

  1. 当用户进程调用了recvfrom()这个系统调用,希望从磁盘获取数据
  2. kernel就开始了IO的第一个阶段,准备数据,如果数据需要很长时间,那么就需要一直等待
  3. kernel数据准备好了,会将数据从kenel中拷贝到用户进程内存,然后kernel返回数据结果,用户进程才解除阻塞状态,可以做其他事情

总结,同步阻塞IO的特定就是在IO执行的两个阶段都被阻塞了。那么也就意味着一个进程只能响应一个用户请求,剩下请求会被挂起,会造成每次只能响应一个请求。

同步非阻塞IO

  1. 当用户进程调用了recvfrom()这个系统调用,希望从磁盘获取数据
  2. 那么是否完成并不知道,需要一次一次的去问
  3. kernel中的数据准备好了,此时用户进程再次发起系统调用,那么它马上将数据拷贝到了用户进程内存。

所以,非阻塞IO的特点是用户进程需要不断的主动询问kernel数据好了没有
好处:用户进程可以处理其他任务
坏处:任务完成的响应延迟增大了,因为每过一段时间采取轮询一次操作

IO多路复用

  1. 当用户进程发起调用请求,不用直接与内核交互,而是找一个代理进程select,当用户进程调用select,那么整个进程会阻塞在select上(因为是由select与内核进行交互,需要等待select返回结果)
  2. kernel会监视select负责的数据,当任何一个进程的数据准备好了,select就会返回
  3. select用户进程返回结果后,用户程序会再次进行系统调用,将kernel数据拷贝到用户进程

总结,select代理进程,它这一个进程可以接收多个用户进程的请求

信号驱动IO

  1. 当用户进程调用了recvfrom()这个系统调用,希望从磁盘获取数据
  2. 磁盘文件中的数据如果还没有读取到内核缓冲区时,没关系,进程还可以继续运行并不阻塞
  3. 当磁盘数据复制到内核中后,会通知用户进程数据准备就绪
  4. 用户进程在发指定将内核中数据复制到用户进程中,此时进程会进入阻塞状态

异步非阻塞IO

  1. 当用户进程调用了recvfrom()这个系统调用,希望从磁盘获取数据
  2. kernel收到后,会立刻返回,所以不会对用户进程产生任何阻塞
  3. kernel等待数据准备完成,并将内核数据拷贝到用户进程内存,当这一切完成之后,kernel会给用户进程发送一个回调函数通知用户进程本次IO完成。

IO模型对比

file

IO模型实现

几种网络IO模型实现

select:对应IO/复用模型,遍历
Poll:对应IO/复用模型
Epoll对应IO/复用模型,具有信号驱动I/O模型某些特性

select、poll、epool区别

无论是select、poll、epool都可以面对多个用户进程的请求,它相当于一个代理人,收集很多用户进程的请求,收集完成后,它帮你从磁盘上获取数据,复制到内核中,俺么这个数据准备没准备好,它的实现机制是不一样的。

通知方式:假设有一个用户数据准备好了,那么还有很多用户数据没准备好,那么如何通知呢?

  1. selectpoll是遍历扫描,效率低下
  2. epoll采用回调机制,epoll会主动通知,效率会更高

IO效率:假设100个用户发请求和1000个用户发请求,在遍历的时候的性能一样吗?

  1. selectpoll用户的请求越多,所需要遍历的就越多,需要耗时就越长
  2. epoll采用的是回调方式,无论有多少用户,它发送的时间是一样的。

总结:

  1. nginx从最初设计时,就是使用epoll IO模型,使用边缘触发机制
  2. 同时nginx还支持异步IO,用了近几年最新的服务端编程技术,来支持较好的并发。
最后修改日期: 2024年3月26日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。