当前位置: 首页 > article >正文

Input/Output模型

  I/O在计算机里指的是INPUT/OUTPUT,也就是输入/输出。IOPS即每秒钟的输入输出量。I/O的工作机制就是把数据从内核空间中的内存数据复制到用户空间中进程的内存当中。

  Linux的I/O

  • 磁盘I/O

    磁盘I/O是进程向内核发起系统调用,请求磁盘上的某个资源,然后通过相应的驱动程序将目标文件加载到内核的内存空间,加载完成后把数据从内核内存再复制给进程内存,如果是比较大的数据也需要等待时间。

  • 网络I/O:一切皆文件,本质为对socket文件的读写

    网络通信就是网络协议栈到用户空间进程的IO就是网络IO

1.客户端发起请求 先发送到网卡   
2.网卡收到的报文复制到内核空间
3.内核空间再复制到用户空间的应用程序空间
4.nginx 分析得到一个磁盘页面文件
5.再将需求反馈给内核空间,应为应用程序没有权限从磁盘上直接读取文件,需要依靠内核
6.内核去磁盘上找到所需要的文件,加载到内核空间
7.加载后再复制到用户空间
8.用户空间构建响应报文,交给内核空间,内核空间再复制给网卡,返回给用户
整个过程会来回切换 用户空间,内核空间  那么我们可以再次基础上做优化处理

简单来说,A(nginx)--------->B(内核),A程序布置一个任务给B,B的任务就是找到某个文件,先复制内核,再复制给我。

  零拷贝技术

    传统的Linux系统的标准I/O借口是基于数据拷贝的,也就是数据都是“拷贝给用户”或者“从用户那儿拷贝”。

    优点:通过中间缓存的机制,减少磁盘I/O的操作

    缺点:消耗大量CPU资源,降低传输速率。

  MMAP

     mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问

    mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。

    优点:可以实现不同进程中的文件共享,适合数据大量传输。

  1. I/O模型相关概念

    同步/异步(消息反馈机制) :关注的是消息通讯机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。

    同步:被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成。简而言之,发起者需要主动联系执行者是否完成。

    异步:被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态。简而言之,执行者会自动反馈,是否完成。

    阻塞/非阻塞: 关注调用者在等待结果返回之前所处的状态

    阻塞:指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。简而言之,只可以做一件事,必须要等这件事情完成才能进行下一件事。

    非阻塞:指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。简而言之,在等待时间可以做其他事。

  2. 网络I/O模型

    阻塞型、非阻塞型、复用型、信号驱动型、异步

  2.1 阻塞性I/O模型

    阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然后将接收的数据拷贝到用户空间,完成read操作用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

    优点:基本不占用资源

    缺点:为何程序、内存、线程切换开销较大

  2.2 非阻塞性I/O模型

    用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等,那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长,程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。

  2.3 多路复用I/O型

    I/O multiplexing 主要包括:select,poll,epoll三种系统调用,select/poll/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。Apache prefork是此模式的select,work是poll模式。

  2.4 信号驱动式I/O模型

    调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个SIGIO 信号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进程所需要的数据从内核空间拷贝到用户空间。 

   当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。

  • 优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此可以提高资源的利用率
  • 缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

  2.5 异步I/O模型

    异步I/O是由内核通知我们I/O操作何时完成,所有事情都交给内核处理。

    异步I/O与信号驱动I/O的区别

  • 信号驱动I/O:何时开始一个IP操作
  • 异步I/O是由内核通知我们I/O操作何时完成

    ginx支持在多种不同的操作系统实现不同的事件驱动模型,但是其在不同的操作系统甚至是不同的系统版本上面的实现方式不尽相同,主要有以下实现方式:

selectpollepoll
操作方式遍历遍历回调
底层实现数组链表哈希表
IO效率每次调用都是线性遍历,时间复杂度O(n)每次调用都是线性遍历,时间复杂度O(n)事件通知方式,每当fd就绪,系统注册的回调函数就会被调用,将就绪的rdlllist,事件复杂度O(1)
最大连接数

1024(x86)

2048(x64)

无上限无上限
fd拷贝每次调用都要把fd集合从用户拷贝到内核态每次调用poll都需要把fd集合从用户态拷贝到内核态调用epoll_ctl时拷贝近内核并保存,之后每次epoll_wait不拷贝
缺点

1.数量受到限制

2.效率降低

3.开销成本大

1.数量受到限制

2.效率降低

3.开销成本大

使用次数基本不用目前主流

    select和epoll的区别

select:会轮询遍历所有的事件集合,其次遍历的事件个数有限制

epoll:只会遍历已准备好的事件集合,事件个数无限制


http://www.kler.cn/a/272299.html

相关文章:

  • C++ ——— 模拟实现 vector 类
  • MySQL表的增删改查(基础)CRUD
  • mfc操作json示例
  • Dockerfile -> Docker image -> Docker container
  • 基于springboot的口腔管理平台
  • 数据结构与算法之查找: LeetCode 69. x 的平方根 (Ts版)
  • 银行信息系统应用架构导论-引用
  • 【C语言基础篇】字符串函数strlen的介绍及模拟实现
  • Word2vec 学习笔记
  • mac安全干净卸载Anaconda3
  • 安装使用sqlite
  • ChatGPT编程实现简易聊天工具
  • What Can ChatGPT Tell Us About the Evolution of Artificial Intelligence?
  • ​使用PotPlayer播放器查看软解和硬解4K高清视频时的CPU及GPU占用情况​
  • LabVIEW电液伺服作动器
  • 【C++ 08】vector 顺序表的常见基本操作
  • Python——pgzero游戏打包exe执行时报错
  • 【Docker】常用命令 docker ps
  • pyinstaller打包不显示DOS窗口
  • 【GPT-SOVITS-03】SOVITS 模块-生成模型解析
  • LabVIEW电磁阀特性测控系统
  • UnityShader:IBL
  • 【洛谷 P9242】[蓝桥杯 2023 省 B] 接龙数列 题解(线性DP+二维数组)
  • -bash-4.2$
  • Lua中文语言编程源码-第六节,更改lmathlib.c 数学库函数, 使Lua加载中文库关键词(与数学库相关)
  • docker-compose是什么