BOI,NIO和IO多路复用器

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

优点规避了频繁的调用系统函数,减少了用户态陷入内核态的次数。