一、IO模型分类
1、同步阻塞IO(Blocking IO):即传统的IO模型。
2、同步非阻塞IO(Non-blocking IO):默认创建的socket都是阻塞的,
非阻塞IO要求socket被设置为NONBLOCK。
3、异步阻塞IO:即经典的Reactor设计模式,也称为IO多路复用。
4、异步非阻塞IO:即经典的Proactor设计模式。
二、IO操作分为哪些部分:
1、先从磁盘、socket套接字等读取数据到操作系统内存。
2、再从操作系统内存读取数据到用户线程中。
三、同步和异步区别:
1、同步:
IO操作的第一步(数据读取到系统内存之后)完成后,用户线程不会释放,
依然轮询或者阻塞等待,主动向系统内存去请求数据,
当系统内存的数据存入用户线程内存之后,该用户内存才释放。
2、异步:
IO操作的第一步(数据读取到系统内存之后)完成后,用户线程马上释放,
不会阻塞或轮询主动向系统内存请求数据,而是系统内存主动复制数据到
用户线程内存。
3、同步和异步的差异:
针对的IO操作第二步(从操作系统内存读取数据到用户线程),
用户线程与内核的交互方式不同:
同步是用户线程通过等待(阻塞)或者轮询(非阻塞)的方式,
主动向系统内存去请求数据。
异步是系统内核自己将系统内存的数据复制给用户线程。
异步的好处:
用户线程阻塞完第一步(先从磁盘、socket套接字等读取数据到操作系统内存),
就可以释放,去干其它事情了,不用阻塞着等待数据从系统内存复制到用户线程内存。
四、阻塞和非阻塞的区别:
1、阻塞:
用户线程发出请求后,数据读取到系统内存了才会返回,否则一直阻塞等待。
2、非阻塞:
用户线程发出请求后,马上返回结果。如果没有数据没有读取到系统内存,又重新发送。
3、阻塞和非阻塞的差异:
针对IO操作第一步(先从磁盘、socket套接字等读取数据到操作系统内存),
用户线程调用内核IO操作的方式不同:
阻塞IO,会在发送请求让内核读取到数据之后,再释放线程。(线程等待)
非阻塞IO,会在发送请求之后就立刻返回,如果没有数据,就再请求(轮询)。
非阻塞IO好处:
实际上轮询也是会占用cpu资源的,如果是多个socket的话,用非阻塞相当于
可以在cup时间片的切换间隙,访问多个socket。
NIO在一些短业务线,访问量高的程序中使用,会提高系统的吞吐量,
但是对于业务线长,且访问量低的程序来说,就未必是件好事,
使用BIO可能会更好一些,不然线程就会空转,浪费CPU。
五、几种IO模型详解
(1)、同步阻塞IO
同步阻塞IO模型是最简单的IO模型

用户线程发起请求,从磁盘网卡socket等读取数据到系统内存,
然后从系统内存读取数据到用户线程内存,这一整个周期用户线程都是阻塞状态,
要全部完成后才能释放。
(2)、同步非阻塞IO

是在BIO的基础上,将socket设置为NIO(NONBLOCK)。
用户线程发起请求后立刻返回,如果系统内存没有读取到数据,当前线程就会轮询,
直到系统内存读取到数据,然后从系统内存读取数据到用户线程的过程是阻塞的。
NIO的非阻塞是针对于IO操作的第一步,从磁盘网卡socket等读取数据到系统内存时非阻塞,
采用线程轮询的方式。
(3)、IO多路复用(异步阻塞IO)

单独开一个线程去监控多个socket,监控到了某个socket数据可读之后,再开一个线程去执行读取
(从外部读取数据到系统内存)
这样就解决了NIO从外部读取数据到系统内存期间的线程轮询问题。
在从外部读取数据到系统内存期间,当前线程是阻塞状态(阻塞),
读取之后系统内存主动推送数据到用户线程内存(异步)。
这样在处理1000个连接时,只需要1个线程监控就绪状态,
对就绪的每个连接开一个线程处理就可以了,
这样需要的线程数大大减少,减少了内存开销和上下文切换的CPU开销。
(4)、异步非阻塞IO

发送请求之后马上返回,并且不需要轮询,系统内核在把数据复制给用户线程之后,
会通知对应的线程,执行对应的回调。
4万+

被折叠的 条评论
为什么被折叠?



