一、BIO
二、NIO
由NIO的调用图可知,轮询发生在用户空间,联想一下工作中的开发场景:业务系统A需要调用业务系统B的基础服务来查询单个用户的信息;随着业务的发展,A的逻辑变复杂了,需要查100个用户的信息。显然,A希望B提供一个批量查询的接口,用集合作为入参,一次性把数据传递过去就省去了频繁的系统间调用。因此多路复用也是基本按照这个思路进行优化的——将轮询操作放到内核空间!
三、多路复用
多路复用在Linux内核代码迭代过程中依次支持了三种调用,即select、poll、epoll三种多路复用的网络I/O模型。下面是他们三者的区别:
四、select、poll、epoll三者的区别
1、select和poll差别不大,区别就是:select有最大文件描述符个数限制(1024)、poll的数据结构是红黑树;但是他们还是有O(n)复杂度的问题,因为内核会返回所有的文件描述符,具体哪些是真正可读写的需要在用户空间遍历判断。
2、而epoll的复杂度是O(1),返回的"nfds"是一个确定的可读写的数量,相比于select和poll需循环n次来确认,复杂度降低了不少。
五、阻塞、非阻塞和同步、异步
阻塞和非阻塞:读写没有就绪或者读写没有完成,函数是否要一直等待还是采用轮询;
同步和异步:同步是读写由应用程序完成。异步是读写由操作系统来完成,并通过回调的机制通知应用程序。