IO
2021-08-24 22:57:56 0 举报
AI智能生成
IO相关总结
作者其他创作
大纲/内容
Type
BIO
Block IO , 顾名思义 , 同步阻塞
客户端socket发送一个请求,服务端socket进行处理后返回响应,相应必须是等处理完才会返回
在这之前啥也干不了,这可不就是同步么
这种方式最大的坑在于,每次一个客户端接入,都是要服务端创建一个线程来服务这个客户端的
如果有大量客户端的时候,那么服务端的线程数量可能达到几千、几万甚至几十万
然后服务器BOOM
要么搞个线程池,固定数量的线程池来处理
但是高并发又会有各种排队和延时的问题
图示
分支主题
NIO
New IO , 同步非阻塞,基于Reactor模型
Buffer缓冲区,将数据写入Buffer中,然后从Buffer中读取数据
IntBuffer、LongBuffer、CharBuffer等很多种针对基础数据类型的Buffer
Channel,NIO中都是通过Channel来进行数据读写的
Selector,多路复用器
selector会不断轮询注册的channel,如果某个channel上发生了读写时间,selector就会将这些channel获取出来
通过SelectionKey获取有读写时间的channel,就可以进行IO操作
一个Selector就通过一个线程,就可以轮询成千上万个channel,这就意味着你的服务端可以介入成千上万的客户端
核心即非阻塞,selector一个线程就可以不停的轮询缠你了,所有客户端请求都不会阻塞,直接就会进来,大不了排下队
NIO的优化思想就是一个请求一个线程,只有某个客户端发送了一个请求的时候,才会启动一个线程来处理
处理时还是要先读取数据,处理,再返回的,这是个同步的过程
IO磁盘操作时需不断的while询问CPU是否处理完成
图示
分支主题
AIO
Async IO, 异步非阻塞,基于Proactor模型
每个连接发送过来的请求,都会绑定一个buffer,然后通知操作系统去一部完成读
此时你的程序是回去干别的事儿的,等操作系统完成数据读取后,就会回调你的接口,给你操作系统异步读完的数据
然后你对这个数据处理一下,接着讲结果往回写
写的时候也是个操作系统一个buffer,让操作系统自己获取数据去完成写操作,写完以后再回来通知你
工作线程
读取数据的时候,提供给操作系统一个buffer,空的,然后你就可以干别的事儿了,把读数据的事儿交给系统去干
内核读数据将数据放入buffer,完事了,来回调你的一个接口,告诉你说,ok,数据读好了
写同理
同步、非同步、阻塞、非阻塞
BIO
用BIO的流读写文件时,你发起个IO请求直接hang死,必须等搞完了这次IO才能返回
这个针对的是磁盘文件的IO读写
FileInputStream ,BIO,卡在那儿,直到你读写完成了才可以
NIO
通过NIO的FileChannel发起个文件IO操作,其实发起之后就反悔了,你可以干别的事儿,这就是非阻塞
但是接下来你还得不断地去轮询操作系统,看IO操作完事儿了没有
AIO
通过AIO发起个文件IO操作之后,你立马就可以返回干别的事儿了,接下来你也不用管了
操作系统自己干完了IO之后,告诉你说ok了。
同步就是你自己还得主动去轮询操作系统,异步就是操作系统反过来通知你
零拷贝
先来看看普通的一次IO操作吧
File file = new File("XXX.txt");
RandomAccessFile raf = new RandomAccessFile(file,"rw");
byte[] arr = new byte[(int)file.length()];
raf.read(arr);
Socket socket = new ServerSocket(8080).accept();
socket.getOutputStreadm().write(arr);
用户态 -> 内核态 && 磁盘数据 -> DMA引擎拷贝 -> 内核缓冲区
内核态 -> 用户态 && 内核缓冲区数据 -> CPU拷贝 -> 用户缓冲区
用户态 -> 内核态 && 用户缓冲区数据 -> CPU拷贝 -> Socket缓冲区
异步化
Socket缓冲区数据 -> DMA引擎拷贝 -> 网络协议引擎
内核态 -> 用户态
图示
分支主题
mmap内存映射技术
直接将磁盘文件数据映射到内核缓冲区,这个映射过程是基于DMA拷贝的
同时用户缓冲区是跟内核缓冲区贡献一块映射数据的,建立共享映射之后
就不需要从内核缓冲区拷贝到用户缓冲区了
即减少了一次数据拷贝
图示
分支主题
所谓零拷贝
基于linux提供的sendfile,也就是零拷贝技术
用户态 -> 内核态 , 磁盘数据 -> DMA拷贝 -> 内核缓冲区,同时从内核缓冲区拷贝一些offset和length到Socket缓冲区
内核态 -> 用户态 ,内核缓冲区数据 -> DMA拷贝 -> 网络协议引擎 , 同时从Socket缓冲区拷贝一些offset和length到网络协议引擎中
这个offset和length的量很少,几乎可以忽略不计
图示
分支主题
0 条评论
下一页