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