BOI,NIO和IO多路复用器
BIO
即阻塞IO
特点:每线程,每链接
当有新的连接建立时,BIO会抛出一个线程去监听这个连接
从学校到学生家,我们看作线程从用户态到内核态
BIO对于每一个连接都会抛出一个线程去监听连接,并且每个线程调用eccept(), recv()
都会陷入内核态导致资源浪费,效率低下
NIO
NIO在BIO的基础上对每一次eccept,recv()
进行改进,如果有则返回信息,没有则返回-1或null
,之后每隔一段时间(sleep())进行一次轮询(一般先调用eccept()
,在调用对象数组中每一个连接的recv()
)
优点:将阻塞变为非阻塞,使得所有链接可以存入容器,用一个线程就能管理(减少了开销)
缺点:假如有1W个连接,而只有一个连接有信息,但是却要调用1W个recv()
(从用户态到内核态1W次,对应每个老师不管学生有没有问题都要跑到学生家)
IO复用器
IO多路复用器指的是优化了socket连接的API,常用的有select, poll, epoll
select, poll
两者没什么大的不同,主要区别select中有最多只能1024个连接的限制,poll没有
多路复用器在每次轮询前都会先将所有的连接信息发送给内核(poll(fds), 这里fds是指linux系统中会对每个连接贴上一个文件描述符
(整型的)的集合),内核通过遍历文件描述符将有数据的连接的状态改变返回给线程,线程通过返回的状态决定哪个连接要recv()或accept()
优点:解决了NIO中大部分连接“白跑”的现象
缺点:每次都需要带所要连接的信息去内核(为啥,内核不能找个地方吧信息存起来啊)
epoll
优点规避了频繁的调用系统函数,减少了用户态陷入内核态的次数。