UNIX中的五种I/O模型

在Java网络编程中,应用的较多的主要有BIO,NIO俩种模型,前者为传统的阻塞IO模型,后者为Java1.4后来新加入的非阻塞IO模型,由于后者的性能前者要高出很多,所以开发高性能的应用时,基本都会选择NIO模型。最典型的比如大名鼎鼎的Netty框架就是基于NIO开发的(Netty框架几乎无处不在,)。另外还有一种不太常用的Java1.7中新加入的AIO模型,是NIO的2.0版本,应用较少,与NIO的主要区别在于AIO是基于事件回调的。

所有Java的这些IO模型都是基于底层来实现的,我们先来简单了解下操作系统层面上的IO模型,了解之后会对Java的实现理解有一定的帮助。在Unix网络编程一书中定义了5种I/O模型

阻塞式I/O

这是最简单也是最早出现的I/O模型。来看一下该模型的流程图

进行IO操作时,进程调用recvfrom,该函数会一直阻塞直到数据到达或者报错才能返回,从调用recvfrom开始到它返回的整段时间内是被阻塞的。这意味着我们的程序在这段等待的时间内做不了任何事情。

非阻塞I/O

当调用recvfrom没有数据可返回时,内核立即返回一个EWOULDBLOCK错误,直至数据报准备好时,才正常返回。我们可以对它进行轮询,查看是否有数据到来,但是这么做的缺点是比较耗费CPU时间。

I/O复用模型

该模型由select与poll函数支持,这两个函数作用是内核一旦发现进程指定的一个或多个I/O条件就绪时,就会通知进程。

调用select或者poll,使其不阻塞在I/O系统调用上。只阻塞在select或者poll调用,等待数据报套接字变为可读。当套接字返回可读这一条件时,则调用recvfrom把数据读出。该模型的优势在于select可以同时等待多个描述符(一个socket的读写对应一个描述符)就绪。

信号驱动式I/O

与I/O复用模式区别在于,它可以让内核在描述符就绪时发送SIGIO信号通知我们。这种模型优势在于等待数据报到达期间进程不被阻塞。

异步I/O模型

进程会告知内核启动某个操作,并让内核在整个操作完成后通知我们,与信号驱动模型区别在于,信号模型通知我们何时可以启动一个I/O操作,异步模型通知我们I/O操作何时完成。在等待I/O完成期间,我们的进程不被阻塞。

比较

可以看出异步I/O模型的性能是最佳的,几乎阻塞时间。

参考:UNIX网络编程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章