美文网首页
IO模型比较

IO模型比较

作者: 以梦为马驾驾驾 | 来源:发表于2021-11-07 03:47 被阅读0次

IO模型的比较

JAVA的io流和nio有什么区别? - 知乎 (zhihu.com)

首先说一下Stream和Channel的差别

  • Stream是不自动缓冲的,Channel会(操作系统层面的),前者面向字节,一个一个处理,后者面向快(缓冲区)

  • Stream之能工作在阻塞下,而channel都可以

  • 都是全双工的

关于一次Java的IO读写

  1. 读:java需要调用操作系统内核的接口,从用户态转为内核态,将数据读入内核缓冲区,在此期间,用户线程阻塞(虽然java线程表现为RUNNABLE),在此期间,操作系统用DMA来读, 然后挂起操作系统线程,等待DMA将数据准备好,放在操作系统指定的内存区域(内核缓冲区),然后通知操作系统线程,操作系统线程变为可运行,运行,然后cpu将数据拷贝到用户的内存空间。中间有两次拷贝(cpu参加一次,DMA参加一次)。

  2. 写(先写到缓冲区,然后再发送): 内核态切换,cpu先写到Socket缓冲区,回到用户态,再切换到内核态,在使用硬件的DMA拷贝到网卡(cpu参加一次,DMA参加一次)

关于一次java的NIO读写

最大的区别是使用DirectByteBuf,它使用的是操作系统的内存,减少了一次数据拷贝,但是用户内核态的切换次数没有变

进一步优化的“零拷贝”

其实是不拷贝到jvm的内存区域,这主要依赖于linux的进步。(零拷贝适合小文件,大文件适合一次读入内存发送)

Linux2.1的sendFile方法,对应java中队channel调用transferTo/transferFrom

  1. java调用后需要切换内核态,在使用DMA将从磁盘复制到内核缓冲区

  2. 然后cpu将数据从内核缓冲区,拷贝到socket缓冲区

  3. 最后是DMA将socket缓冲区的数据写入网卡

在此期间,一共切换了一次内核态,然后数据复制了三次(没有jvm拷贝)。

Linux2.4 比2.1 ,可以将内核缓冲区的数据直接用DMA发送到网卡,还是有一次内核态切换,但是数据复制又少了一次。

AIO

异步IO需要Kernel支持

  • windows通过IOCP实现了真正的异步IO

  • Linux在2.6版本通过多路复用模拟了异步IO,性能上并没有优势。

零拷贝 : 主要的任务就是避免CPU将数据从一块存储拷贝到另外一块存储,主要就是利用各种零拷贝技术,避免让CPU做大量的数据拷贝任务,减少不必要的拷贝,或者让别的组件来做这一类简单的数据传输任务,让CPU解脱出来专注于别的任务(计算).

当应用程序访问某块数据时,操作系统首先会检查,是不是最近访问过此文件,文件内容是否缓存在内核缓冲区,如果是,操作系统则直接根据read系统调用提供的buf地址,将内核缓冲区的内容拷贝到buf所指定的用户空间缓冲区中去。如果不是,操作系统则首先将磁盘上的数据拷贝的内核缓冲区,这一步目前主要依靠DMA来传输,然后再把内核缓冲区上的内容拷贝到用户缓冲区中。 接下来,write系统调用再把用户缓冲区的内容拷贝到网络堆栈相关的内核缓冲区中,最后socket再把内核缓冲区的内容发送到网卡上。

共产生了四次数据拷贝,即使使用了DMA来处理了与硬件的通讯(两次),CPU仍然需要处理两次数据拷贝,与此同时,在用户态与内核态也发生了多次上下文切换,无疑也加重了CPU负担.

途径:

  • mmap :

    应用程序调用mmap(),磁盘上的数据会通过DMA被拷贝的内核缓冲区,接着操作系统会把这段内核缓冲区与应用程序共享,这样就不需要把内核缓冲区的内容往用户空间拷贝。应用程序再调用write(),操作系统直接将内核缓冲区的内容拷贝到socket缓冲区中,这一切都发生在内核态,最后,socket缓冲区再把数据发到网卡去。 优点 : 少一次IO拷贝, 两次DMA, 一次cpu

    代价: 当你的程序map了一个文件,但是当这个文件被另一个进程截断(truncate)时, write系统调用会因为访问非法地址而被SIGBUS信号终止,SIGBUS信号默认会杀死你的进程并产生一个coredump.

    解决方案: 为sigbus信号建立简单的返回处理, 或者 mmap前,应用程序想内核申请一个此文件的租借锁.

  • sendfile

    三次DMA拷贝数据, 一次cpu拷贝

讲述同步与异步, 阻塞与非阻塞的区别:

同步与异步是: 前者在请求返回的时候, 结果也返回, 后者是请求返回,比如拿到了一个response, 但是并且没有拿到结果, 我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者.

阻塞和非阻塞是: 请求结果返回之前, 前者线程被挂住, 请求结果返回之前, 后者线程可以做其他事情

这两类前者关注, 结果返回的时候, 后者关注调用者本身的状态

IO模型参考文章

select poll epoll 原理 epoll去掉了遍历文件描述符(前二者),而是通过监听回调的的机制。这正是epoll的魅力所在。

相关文章

  • IO模型比较

    IO模型的比较 JAVA的io流和nio有什么区别? - 知乎 (zhihu.com)[https://www.z...

  • NIO selector 多路复用reactor线程模型--20

    多路复用IO模型:多路复用IO模型是目前使用得比较多的模型。JavaNIO实际上就是多路复用IO。在多路复用IO模...

  • 1.Nette入门第一章——IO演进

    1. IO 基础 1.1. linux网络IO模型 阻塞IO模型 非阻塞IO模型 IO多路复用模型(NIO) 信...

  • 细谈Select,Poll,Epoll

    阻塞 io 模型 blocking IO非阻塞 io 模型 nonblocking IOio多路复用模型 IO m...

  • 2.五种IO模型

    0.IO介绍1.阻塞IO模型2.非阻塞IO模型3.IO多路复用模型4.信号驱动IO模型5.异步IO模型6.五种IO...

  • IO 模型知多少 | 代码篇

    引言 之前的一篇介绍IO 模型的文章IO 模型知多少 -- 理论篇比较偏理论,很多同学反应不是很好理解。这一篇咱们...

  • 网络IO模型

    网络IO的模型大致包括下面几种 同步模型(synchronous IO)阻塞IO(bloking IO)非阻塞IO...

  • 「基础知识总结」 IO模型

    IO模型 五种IO模型包括:阻塞IO、非阻塞IO、信号驱动IO、IO多路转接、异步IO。其中,前四个被称为同步IO...

  • 五种 IO 模型

    五种 IO 模型 参考链接 一共有五种 IO 模型 阻塞 IO 非阻塞 IO 多路复用 IO 信号驱动 IO 异步...

  • Java中的IO模型

    Java中的IO模型 Java中的IO模型有四种: 同步阻塞IO 同步非阻塞IO IO多路复用 异步IO 其中IO...

网友评论

      本文标题:IO模型比较

      本文链接:https://www.haomeiwen.com/subject/gciszltx.html