首页 > 其他分享 >脑图系列-操作系统IO

脑图系列-操作系统IO

时间:2024-03-15 13:56:15浏览次数:11  
标签:调用 操作系统 epoll 阻塞 脑图 内核 IO 拷贝

 

同步、异步、阻塞、非阻塞

同步与异步描述的是被调用者的

如果是同步,B在接到A的调用后,会立即执行要做的事。A的本次调用可以得到结果。

  • 让我干活立马就干,立即反馈结果

如果是异步,B在接到A的调用后,不保证会立即执行要做的事,但是保证会去做,B在做好了之后会通知A。A的本次调用得不到结果,但是B执行完之后会通知A。

  • 让我干活,等会干,干完通知你

阻塞与非阻塞描述的是调用者的

如果是阻塞,A在发出调用后,要一直等待,等着B返回结果。

  • 找人干活,等着他干完

如果是非阻塞,A在发出调用后,不需要等待,可以去做自己的事情。

  • 找人干活,自己去忙

同步不一定阻塞,异步也不一定非阻塞。没有必然关系。

举例

  • 老张把水壶放到火上,一直在水壶旁等着水开。(同步阻塞)
  • 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
  • 老张把响水壶放到火上,一直在水壶旁等着水开。(异步阻塞)
  • 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)
  • 概要
  • 1和2的区别是,调用方在得到返回之前所做的事情不一样,一个是等,一个是看电视
  • 1和3的区别是,被调用方对于烧水的处理不一样。一个不会响,一个会响

IO

为了保护操作系统的安全,通过缓存加快系统读写,会将内存分为用户空间和内核空间两个部分。如果用户想要操作内核空间的数据,则需要把数据从内核空间拷贝到用户空间(数据会放到内核空间的page cache中,这种也叫缓存IO)。

客户端处理请求步骤

  • 1、服务器的网络驱动接受到消息之后,向内核申请空间,并在收到完整的数据包(这个过程会产生延时,因为有可能是通过分组传送过来的)后,将其复制到内核空间;
  • 2、数据从内核空间拷贝到用户空间;
  • 3、用户程序进行处理。

linux读操作

 

  • 1、通过read系统调用,向内核发送读请求
  • 2、内核向硬件发送读指令,并等待读就绪
  • 3、DMA把将要读取的数据复制到指定的内核缓存区中
  • 4、内核将数据从内核缓存区拷贝到用户进程空间中

由此诞生了5种IO方式

同步阻塞型IO模型

同步非阻塞型IO模型

  • 在这里recv不管有没有获得到数据都返回,如果没有数据的话就过段时间再调用recv看看,如此循环

IO复用模型

  • 调用recv之前会先调用select或poll,这两个系统调用都可以在内核准备好数据(网络数据已经到达内核了)时告知用户进程,它准备好了,这时候再调用recv时是一定有数据的。因此在这一模型中,进程阻塞于select或poll,而没有阻塞在recv上
  • 就相当于,小J来银行办理业务,大堂经理告诉他现在所有柜台都有人在办理业务,等有空位再告诉他。于是小J就等啊等(select或poll调用中),过了一会儿大堂经理告诉他有柜台空出来可以办理业务了,但是具体是几号柜台,你自己找下吧,于是小J就只能挨个柜台地找。
  • select、poll、epoll
  • select
  • 是最原始的 I/O 多路复用技术,几乎在所有的平台中都支持,它的缺点是最多只能监听 1024 个文件描述符
  • select函数可以监听read,write,except的fd。当select返回后,可以遍历对应的fd_set来寻找就绪的fd,从而进行业务处理
  • 包含大量fd的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,其开销也随着文件描述符数量增加而线性增大
  • poll
  • 在 select 的基础上增加了支持监听更多的文件描述符的能力,但是复杂度随着监听的文件描述符数量的增加而增加
  • 同select一样,poll返回后,也是需要轮询pollfd来获取就绪的fd。不仅如此,所有的fds也是在内核态和用户态中来回切换,也会影响效率
  • 但是因为fds基于链表,所以就没有了最长1024的限制
  • epoll
  • 在 poll 的基础上进一步优化了复杂度,可以支持更多的文件描述符,并且具有更高的效率
  • 每次注册新的事件调用epoll_ctl时,epoll会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
  • epoll会通过epoll_wait查看是否有就绪的fd,如果有就绪的fd,就会直接使用(O(1))。而不是像之前两个一样,每次需要手动遍历才能得到就绪的fd(O(n))
  • epoll是通过epoll_wait来获取就绪的fd,那么如果就绪的fd一直没有被消费,该如何处理呢?
  • LT(level trigger)(默认)模式
  • 当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll_wait时,会再次响应应用程序并通知此事件
  • ET(edge trigger)模式
  • 当epoll_wait检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll_wait时,不会再次响应应用程序并通知此事件。

信号驱动模型

 

 

  • 此处会通过调用sigaction注册信号函数,在内核数据准备好的时候系统就中断当前程序,执行信号函数(在这里调用recv)
  • 小J让大堂经理在柜台有空位的时候通知他(注册信号函数),等没多久大堂经理通知他,因为他是银行的VIPPP会员,所以专门给他开了一个柜台来办理业务,小J就去特席柜台办理业务了。但即使在等待的过程中是非阻塞的,但在办理业务的过程中依然是同步的。

异步IO模型

 

  • 调用aio_read令内核把数据准备好,并且复制到用户进程空间后执行事先指定好的函数
  • 小J交代大堂经理把业务给办理好了就通知他来验收,在这个过程中小J可以去做自己的事情。这就是真正的异步IO。

零拷贝

 

  • 如果不考虑用户态的内存拷贝和物理设备到驱动的数据拷贝,我们会发现,这其中会涉及4次数据拷贝。同时也会涉及到4次进程上下文的切换
  • 对于Java程序,还会多了一个堆外内存和堆内存之间的copy

所谓的零拷贝,作用就是通过各种方式,在特殊情况下,减少数据拷贝的次数/减少CPU参与数据拷贝的次数

常见的零拷贝方式有mmap,sendfile,dma,directI/O等

扩展

  • DMA
  • 正常的IO流程中,不管是物理设备之间的数据拷贝,如磁盘到内存,还是内存之间的数据拷贝,如用户态到内核态,都是需要CPU参与的
  •  

  • 如果是比较大的文件,这样无意义的copy显然会极大的浪费CPU的效率,所以就诞生了DMA
  • DMA的全称是Direct  Memory Access,顾名思义,DMA的作用就是直接将IO设备的数据拷贝到内核缓冲区中。使用DMA的好处就是IO设备到内核之间的数据拷贝不需要CPU的参与,CPU只需要给DMA发送copy指令即可,提高了处理器的利用效率
  •  

  • mmap
  • mmap,全称是memory map,翻译过来就是内存映射,顾名思义,就是将内核态和用户态的内存映射到一起,避免来回拷贝 
  •  

  • 采用mmap + write的方式,内存拷贝的次数会变为3次,上下文切换则依旧是4次。
  • 问题
  • mmap 使用时必须实现指定好内存映射的大小,因此 mmap 并不适合变长文件;
  • 因为mmap在文件更新后会通过OS自动将脏页回写到disk中,所以在随机写很多的情况下,mmap 方式在效率上不一定会比带缓冲区的一般写快
  • 因为mmap必须要在内存中找到一块连续的地址块,如果在 32-bits 的操作系统上,虚拟内存总大小也就 2GB左右(32位系统的地址空间最大为4G,除去1G系统,用户能使用的内存最多为3G左右(windows内核较大,一般用户只剩下2G可用)。),此时就很难对 4GB 大小的文件完全进行 mmap,所以对于超大文件来讲,mmap并不适合
  • sendfile
  • 如果只是传输数据,并不对数据作任何处理,可以通过sendfile的方式,只做文件传输,而不通过用户态进行干预 
  •  

  • 为什么内核要拷贝两次(page cache -> socket cache),能不能省略这个步骤?
  • sendfile + DMA Scatter/Gather
  • DMA gather是LInux2.4新引入的功能,它可以读page cache中的数据描述信息(内存地址和偏移量)记录到socket cache中,由 DMA 根据这些将数据从读缓冲区拷贝到网卡,相比之前版本减少了一次CPU拷贝的过程 
  •  

  • direct I/O
  • 之前的mmap可以让用户态和内核态共用一个内存空间来减少拷贝,其实还有一个方式,就是硬件数据不经过内核态的空间,直接到用户态的内存中,这种方式就是Direct I/O。换句话说,Direct I/O不会经过内核态,而是用户态和设备的直接交互,用户态的写入就是直接写入到磁盘,不会再经过操作系统刷盘处理。
  • 这样确实拷贝次数减少,读取速度会变快,但是因为操作系统不再负责缓存之类的管理,这就必须交由应用程序自己去做,譬如MySql就是自己通过Direct I/O完成的,同时MySql也有一套自己的缓存系统
  • 同时,虽然direct I/O可以直接将文件写入磁盘中,但是文件相关的元信息还是要通过fsync缓存到内核空间中

标签:调用,操作系统,epoll,阻塞,脑图,内核,IO,拷贝
From: https://www.cnblogs.com/leskang/p/18075236

相关文章

  • 【数据挖掘】实验1:R入门(内含详细R和RStudio安装教程)
    实验1:R入门一:实验目的与要求1:根据上课PPT内容,掌握课堂知识并进行代码练习操作,提供练习过程和结果。2:可COPY代码运行结果直接提交,如涉及到输出图等可截图。二:实验内容1:R语言的下载与安装1.1:安装R语言从清华镜像网站(TheComprehensiveRArchiveNetwork)处下载Windows版......
  • aardio教程一) 基础语法-上
    前言想开发一些小工具,所以想系统性的学习一遍aardio,之前都是哪里不会搜哪里,顺便写些教程。我的主要语言是Python,所以会以Python作为对比来加深印象。aardio的基础语法和JavaScript基本类似,如果你学过JavaScript,aardio很容易上手。下面的文档来自官方文档[1]问题搜索途径基础......
  • HTB_pwn_pet_companion_exp
    frompwnimport*context.log_level='debug'elf=ELF('./pet_companion')io=remote('94.237.54.152',51111)padding=72pop_rdi=0x0000000000400743#:poprdi;retpop_rsi=0x0000000000400741#:poprsi;retpayload=b......
  • 1秒AI出图的时代来了!Stable Diffusion WebUI Forge+SVD整合包
    速度快N倍!StableDiffusionWebUIForge整合包要说今年绘画圈最大的新秀那妥妥的就StableDiffution本次更新的StableDiffusionWebUIForge整合包+SVD比之前推送的更加智能、快速和简单有多简单呢?这么说吧之前的版本需要初中生级别现在的的幕后网整合包加强版小......
  • Java-IoUtil扩展工具类
    现在记录下IO扩展支持importlombok.extern.slf4j.Slf4j;importorg.apache.commons.lang3.StringUtils;importjava.io.*;importjava.util.HashMap;@Slf4jpublicclassTyIoUtil{//缓存文件头信息-文件头信息publicstaticfinalHashMap<String,String>......
  • P3643 [APIO2016] 划艇
    题意:在首尔城中,汉江横贯东西。在汉江的北岸,从西向东星星点点地分布着\(N\)个划艇学校,编号依次为\(1\)到\(N\)。每个学校都拥有若干艘划艇。同一所学校的所有划艇颜色相同,不同的学校的划艇颜色互不相同。颜色相同的划艇被认为是一样的。每个学校可以选择派出一些划艇参加节日......
  • Spring IOC与工厂模式
    1.简单介绍在讲SpringIOC之前,有必要先来聊一下工厂模式(FactoryPattern)。工厂模式可将Java对象的调用者从被调用者的实现逻辑中分离出来。工厂模式是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象......
  • 想学一门技术或者搞副业,学什么最靠谱?当然是Python!清华教授35天python教程脑图,让你学习
    想学一门技术或者搞副业,学什么最靠谱?派森君告诉你:当然是Python。为什么呢?Python语言是所有语言中最好上手的语言,简单易学。只要是懂一点英语,逻辑思维不是很差的人很快就能学会。一方面Python作为一门全场景编程语言,当前的应用边界在不断扩展,相信随着大数据、人工智能等技......
  • eclipse 问题之一:Plugin execution not covered by lifecycle configuration
    1、问题eclipse作为java工程的开发工具,可以集成maven直接管理maven工程。但是对于maven工程中描述的插件,有时候eclipse会报如下错误(示例:Pluginexecutionnotcoveredbylifecycleconfiguration:org.codehaus.mojo:exec-maven-plugin:3.1.1:java(execution:default......
  • 猫头虎分享已解决Bug || 网络攻击(Network Attack):DDoSError, NetworkIntrusion
    博主猫头虎的技术世界......