BIO模型
BIO模型也称为同步非阻塞模型,当ServerSocket需要accept()、read()、write()时,调用操作系统的相关函数,但是如果没有拿到对应的数据时,会一直阻塞在那里。
当服务器每接收一个Client就需要开启一个线程去处理
在现在访问量如此之大的条件下,C10K问题是无法避免的,一台服务器根本无法开启如此之多的线程来处理
那么在硬件方面是否可以解决,答案是可以。但是N多台服务器分布式,你想想,这在经济方面是非常昂贵的,很多公司是承担不起的,而且你为每个用户开启一个线程,你能确保每个用户都频繁操作吗?
用户没有平凡的操作,又有如此多的线程需要切换,效率及其的底下。
因此NIO就来解决此问题了。
NIO模型(同步非阻塞)
Select触发事件时是异步的,IO的读、写都是同步的
1.单纯的NIO模型
由于每个socket设置为非阻塞,那个一个线程就可以处理非常多的客户端了,C10K问题得到了进一步的解决
但是现在的性能还不够好,你在用户app中遍历Clien,都需要每次调用kernel系统函数都需要CPU在用户态和内核态的切换,比如你有10个客户端,那么就需要调用10次,也要切换10次
2.NIO加上Select 多路复用器
Select多路复用器的使用,减少了很多无效的Kernel调用,提升了效率。
调用一个Select(),传入所有的fd集合,在内核中遍历。
3.Linux Kernel中select、poll、epoll的区别
buffer存在用户进程中
首先select 和poll 是属于用一类的,多路复用器存贮的Buffer 放在用户App中。
select 是用数组存放的,默认数组大小是1024,所以说连接的数量是有限的。而poll是用链表存贮的,所有说理论上是可以连接无限个(实际受内存影响)
epoll的buffer存在 kernel 中
消息发到网卡中,触发中断机制,cpu就会将网卡的buffer 推送到kernel的网络协议栈中,然后将所有的buffer绑定,当buffer中有事件触发,就将触发事件的fd存在就绪队列中,等待用户select()是就可以直接放回就绪队列,最后由用户app遍历触发的事件(同步的IO操作)。