沙井网站制作,智慧团建官网登录口入口,做360全景有什么网站,前端开发网站开发文章目录 前言1、内核空间和用户空间2、用户态和内核态3、上下文切换4、虚拟内存5、DMA技术6、传统 IO 的执行流程 一、阻塞IO模型二、非阻塞IO模型三、IO多路复用模型1、IO多路复用之select2、IO多路复用之epoll3、总结select、poll、epoll的区别 四、IO模型之信号驱动模型五、… 文章目录 前言1、内核空间和用户空间2、用户态和内核态3、上下文切换4、虚拟内存5、DMA技术6、传统 IO 的执行流程 一、阻塞IO模型二、非阻塞IO模型三、IO多路复用模型1、IO多路复用之select2、IO多路复用之epoll3、总结select、poll、epoll的区别 四、IO模型之信号驱动模型五、IO 模型之异步IO(AIO)总结 前言
在学习IO模型前需要先了解些基础概念才能理解IO的执行流程及阻塞的原因
1、内核空间和用户空间 我们电脑上跑着的应用程序其实是需要经过操作系统才能做一些特殊操作如磁盘文件读写、内存的读写等等。因为这些都是比较危险的操作不可以由应用程序乱来只能交给底层操作系统来。 因此操作系统为每个进程都分配了内存空间一部分是用户空间一部分是内核空间。内核空间是操作系统内核访问的区域是受保护的内存空间而用户空间是用户应用程序访问的内存区域。
内核空间主要提供进程调度、内存分配、连接硬件资源等功能用户空间提供给各个程序进程的空间它不具有访问内核空间资源的权限 如果应用程序需要使用到内核空间的资源则需要通过系统调用来完成进程从用户空间切换到内核空间完成相关操作后再从内核空间切换回用户空间 我们应用程序是跑在用户空间的它不存在实质的IO过程真正的IO是在操作系统执行的。即应用程序的IO操作分为两种动作IO调用和IO执行。IO调用是由进程(应用程序的运行态)发起而IO执行是操作系统内核的工作。此时所说的IO是应用程序对操作系统IO功能的一次触发即IO调用。
2、用户态和内核态
如果进程运行于内核空间被称为进程的内核态如果进程运行于用户空间被称为进程的用户态
3、上下文切换 CPU寄存器是CPU内置的容量小、但速度极快的内存。而程序计数器则是用来存储 CPU正在执行的指令位置、或者即将执行的下一条指令位置。它们都是CPU在运行任何任务前必须的依赖环境因此叫做CPU上下文。 CPU上下文切换就是先把前一个任务的CPU上下文也就是CPU寄存器和程序计数器保存起来然后加载新任务的上下文到这些寄存器和程序计数器最后再跳转到程序计数器所指的新位置运行新任务。 一般我们说的上下文切换就是指内核操作系统的核心在CPU上对进程或者线程进行切换。进程从用户态到内核态的转变需要通过系统调用来完成。系统调用的过程会发生CPU上下文的切换。 4、虚拟内存
现代操作系统使用虚拟内存即虚拟地址取代物理地址使用虚拟内存可以有2个好处 虚拟内存空间可以远远大于物理内存空间多个虚拟内存可以指向同一个物理地址 正是多个虚拟内存可以指向同一个物理地址可以把内核空间和用户空间的虚拟地址映射到同一个物理地址这样的话就可以减少IO的数据拷贝次数啦。 5、DMA技术 DMA英文全称是Direct Memory Access即直接内存访问。DMA本质上是一块主板上独立的芯片允许外设设备和内存存储器之间直接进行IO数据传输其过程不需要CPU的参与。 用户应用进程调用read函数向操作系统发起IO调用进入阻塞状态等待数据返回CPU收到指令后对DMA控制器发起指令调度DMA收到IO请求后将请求发送给磁盘磁盘将数据放入磁盘控制缓冲区并通知DMADMA将数据从磁盘控制器缓冲区拷贝到内核缓冲区DMA向CPU发出数据读完的信号把工作交换给CPU由CPU负责将数据从内核缓冲区拷贝到用户缓冲区用户应用进程由内核态切换回用户态解除阻塞状态 DMA的主要作用就是将数据从磁盘拷贝到内核缓冲区这期间可以解放CUP去做其他事。
6、传统 IO 的执行流程
传统的IO流程包括read和write的过程 read把数据从磁盘读取到内核缓冲区再拷贝到用户缓冲区write先把数据写入到socket缓冲区最后写入网卡设备
流程图如下 读数据 用户应用进程调用read函数向操作系统发起IO调用上下文从用户态转为內核态切换1DMA控制器把数据从磁盘中读取到内核缓冲区CPU把内核缓冲区数据拷贝到用户应用缓冲区上下文从内核态转为用户态切换2read函数返回 写数据 用户应用进程通过write函数发起IO调用上下文从用户态转为内校态切换3CPU将应用缓冲区中的数据拷贝到socket缓冲区DMA控制器把数据从socket缓冲区拷贝到网卡设备上下文从内校态切换回用户态切换4)write函数返回 从流程图可以看出传统IO的读写流程包括了4次上下文切换4次用户态和内核态的切换4次数据拷贝两次CPU拷贝以及两次的DMA拷贝。
一、阻塞IO模型 应用程序的进程发起IO调用但是如果内核的数据还没准备好的话那应用程序进程就一直在阻塞等待一直等到内核数据准备好了从内核拷贝到用户空间才返回成功提示此次IO操作称之为阻塞IO。 阻塞IO比较经典的应用就是阻塞socket、Java BIO阻塞IO的缺点就是如果内核数据一直没准备好那用户进程将一直阻塞浪费性能可以使用非阻塞IO优化
二、非阻塞IO模型 如果内核数据还没准备好系统调用会立即返回一个调用失败的信息让它不需要等待而是通过轮询的方式再来请求。如果内核数据准备好在数据从内核拷贝到用户空间期间是阻塞的因为现在是CUP在操作之前准备数据是DMA。 同步非阻塞 IO 的优点是每次发起的IO系统调用在内核等待数据过程中可以立即返回用户线程不会阻塞实时性较好同步非阻塞IO的缺点是不断地轮询内核这将占用大量的CPU时间效率低下
三、IO多路复用模型 在这之前我们先来复习下什么是文件描述符fd(File Descriptor)它是计算机科学中的一个术语形式上是一个非负整数。当程序打开一个现有文件或者创建一个新文件时内核向进程返回一个文件描述符。 IO复用模型核心思路系统给我们提供一类函数(如我们耳濡目染的select、poll、epoll函数)它们可以同时监控多个fd的操作任何一个返回内核数据就绪应用进程再发起recvfrom系统调用。
1、IO多路复用之select 应用进程通过调用select函数可以同时监控多个fd在select函数监控的fd中只要有任何一个数据状态准备就绪了select函数就会返回可读状态这时应用进程再发起recvfrom请求去读取数据。 非阻塞IO模型(NIO)中需要N(N1)次轮询系统调用然而借助select的IO多路复用模型只需要发起一次询问就够了,大大优化了性能。 select缺点 监听的IO最大连接数有限在Linux系统上一般为1024select函数返回后是通过遍历fdset找到就绪的描述符fd。(仅知道有I/O事件发生却不知是哪几个流所以遍历所有流) 因为存在连接数限制所以后来又提出了poll。与select相比poll解决了连接数限制问题。但是呢select和poll一样还是需要通过遍历文件描述符来获取已经就绪的socket。如果同时连接的大量客户端在一时刻可能只有极少处于就绪状态伴随着监视的描述符数量的增长效率也会线性下降。因此经典的多路复用模型epoll诞生。
2、IO多路复用之epoll 为了解决select/poll存在的问题多路复用模型epoll诞生它采用事件驱动来实现。 epoll先通过epoll_ctl()来注册一个fd(文件描述符)一旦基于某个fd就绪时内核会采用回调机制迅速激活这个fd当进程调用epoll_wait()时便得到通知。这里去掉遍历文件描述符的操作而是采用监听事件回调的机制。这就是epoll的亮点。
3、总结select、poll、epoll的区别
selectpollepoll底层数据结构数组链表红黑树和双链表获取就绪的fd遍历遍历事件回调事件复杂度O(n)O(n)O(1)最大连接数1024无限制无限制fd数据拷贝每次调用select需要将fd数据从用户空间拷贝到内核空间每次调用poll需要将fd数据从用户空间拷贝到内核空间使用内存映射(mmap)不需要从用户空间频繁拷贝fd数据到内核空间 epoll明显优化了IO的执行效率但在进程调用epoll_wait()时仍然可能被阻塞。能不能酱紫不用我老是去问你数据是否准备就绪等我发出请求后你数据准备好了通知我就行了这就诞生了信号驱动IO模型。
四、IO模型之信号驱动模型 信号驱动IO不再用主动询问的方式去确认数据是否就绪而是向内核发送一个信号(调用sigaction的时候建立一个SIGIO的信号)然后应用用户进程可以去做别的事不用阻塞。当内核数据准备好后再通过SIGIO信号通知应用进程数据准备好后的可读状态。应用用户进程收到信号之后立即调用recvfrom去读取数据。 信号驱动IO模型在应用进程发出信号后是立即返回的不会阻塞进程。它已经有异步操作的感觉了。但是你细看上面的流程图发现数据复制到应用缓冲的时候应用进程还是阻塞的。回过头来看下不管是BIO还是NIO还是信号驱动在数据从内核复制到应用缓冲的时候都是阻塞的。还有没有优化方案呢?AIO真正的异步IO
五、IO 模型之异步IO(AIO) AIO也就是NIO2。Java7中引入了NIO的改进版NIO2它是异步IO模型。 AIO 用来解决数据复制阶段的阻塞问题 同步意味着在进行读写操作时线程需要等待结果还是相当于闲置异步意味着在进行读写操作时线程不必等待结果而是将来由操作系统来通过回调方式由另外的线程来获得结果
总结 阻塞、非阻塞、同步、异步IO划分 BIO、NIO、AIO 同步阻塞(blocking-IO)简称BIO同步非阻塞(non-blocking-IO)简称NIO异步非阻塞(asynchronous-non-blocking-IO)简称AIO