linux五种io模型:
1.同步阻塞io,如read函数。调用read后必须等到,从用户态到系统态,阻塞直到有数据准备好然后将数据从内核拷到用户进程。
2.非阻塞io。调用读取函数后,如果没有数据立即返回。这需要用户进程不断的调用读取函数。
3.io复用。同步非阻塞。与非阻塞io差不多,只不过可以注册多个io句柄。用的技术有poll,select,epoll。
select缺点:
a.只支持最多1024个FD文件操作符
b.性能低:每次注册文件句柄或者如果当前句柄事件就绪都内核会返回完整的句柄,然后应用进程一个个再轮循。
epoll则突破了这个限制,基本1G的内存可超过10万。
4.信号驱动。同步非阻塞。系统调用读取函数,操作系统注册一个信号,然后马上返回。之后数据准备好后通知进程,进程之后进行系统调用将数据从内核拷到用户进程。
与多路复用相比在select阶段也不做阻塞:通过注册一个信号处理程序。
这个信号处理程序包含了后续调用recvfrom读取数据的逻辑。与非阻塞单句柄读取相比优点是可以同时注册多个句柄。
5.异步非阻塞io。jdk7有提供AsynchronousServerSocketChannel。用户调用读取函数后(参数中有回调处理函数),操作系统会注册这个回调处理函数。之后数据准备好后操作系统会将数据拷到进程空间,最后发送信号给进程。进程最后对数据进行处理。
异步与同步区别在于,数据从内核拷贝到用户进程空间这部分用户进程是否要同步等待。
同步,指调用一个方法获取结果时,这个结果是否有了是要自己去主动关注的。异步则是由另外一个角色通知。
阻塞指在调用一个方法获取结果时,如果结果还不可用,则该线程就挂起在那里了,不能做其它事情,效率低下。
epoll, select,poll属多路复用。本质上还是同步非阻塞。优势在于,可以一个线程监听处理多个socket事件。提升资源利用率。