深入分析IO模型


这篇文章我为什么叫做深入分析IO模型呢,并不是因为我分析的有多深入,而是应为为了研究清楚这IO模型,我确实花了很多时间,查了很多资料。我想大多数人对这一块儿也有疑问,而且我想网上哪些文章讲的原理看过一遍又一遍之后又会有新的疑问,甚至有些文章讲的都是错的还被抄来抄去。我也不确定我写的能否给大家讲明白,姑且先记下来吧。

我们要讲IO模型,我不像网上的一些文章,上来就讲 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO、异步IO等的原理,也不讲 同步、异步、阻塞、非阻塞 的区别和联系,更不想讲 多路复用IO中 select、poll、epoll 的三种实现。虽然后面都会讲到,我先讲一下啥叫IO。

啥叫IO

IO:计算机中指Input/Output,也就是输入和输出。
IO操作:我们向某个设备写入或读出数据的操作就叫做IO操作,那这些设备都有哪些呢-磁盘、缓存、寄存器、网络、文件等等。我们往操作系统方面考虑,Linux操作系统抽象出来了文件系统这么一个东西,使得对所有设备的操作都可以像操作文件一样,这句话怎么理解呢?我们对文件的所有操作主要包括 创建、读取文件内容、向文件写入内容、关闭文件、删除文件,linux系统的开发者发现通过操作系统控制键盘、显示器、内存、网络等等也逃不出以上类似的操作-打开设备、读取设备内容、向设备写入内容、卸载设备、移除设备。其实这句话得对操作系统中的文件系统有一定的了解后才会理解。可以先学习一下文件系统相关知识。
IO模型: 研究IO操作过程的具体实现方法的理论

Linux IO 与 Java IO

Linux IO 其实指的是更为底层的IO, 而Java IO更多的是指应用层的IO,所以说Java 的IO 模型的实现其实是依赖底层的Linux IO的实现的。
Linux IO 有5种,分别叫 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO、异步IO. 但java只支持其中的三种,Java IO的分类分别叫 BIO、NIO、AIO
其中 BIO 对应 Linux IO 中的阻塞IO实现; NIO对应的其实是 Linux IO中的多路复用IO;AIO 则对应LINUX IO中的异步IO,这一点一定要记清楚,否则后面的概念容易混淆。

Linux IO 模型

上面说到 Linux IO 有5种,分别叫 阻塞IO、非阻塞IO、多路复用IO、信号驱动IO、异步IO。我们思考一下几个问题
服务器如何读取网络上传递过来的一条消息的->首先两台服务器之间进行3次握手建立连接,你可以想象,你的计算机上运行着一个叫tcp的软件,这个软件呢可以打开某个端口,所谓打开端口,就是说可以通过这个端口接收到网络上定向发送给该端口的0101的数据。当网络上的数据通过该端口发送过来消息的时候,其实就是当第一个高电平传输过来的时候,这个tcp软件就会被cpu叫醒,cpu为什么去叫醒tcp软件是因为高电平传过来的时候给了操作系统一个信号中断,然后这个tcp软件发现有数据到达,于是在计算机上申请一块儿内存用于记录通过该端口传过来的数据,这块儿内存其实就是一个socket,他像个插座一样连接你的应用程序和网络上的数据,同时为了表示一个socket我们像上面提到的文件系统申请了一个文件描述符,文件描述符表面上像一个数字,其实背地里它代表一种数据结构的。而我们的应用程序要读取到网路中传输过来的数据,其实就是从这个socket中读取数据。但是我们在向socket读取数据读不到的时候采取什么样的策略决定了我们属于什么模型。

阻塞IO

我们从头捋一遍我们应用程序从启动到接收数据的过程,首先我们应用程序先调用系统方法去监听某个接口,所谓监听其实就是告诉操作系统当有数据从我监听的端口经过的时候,你通知我这个应用程序而不是其他的应用程序,这就是为什么我们一个应用占用一个端口的时候其他应用是无法再继续监听该端口的,会报出端口冲突的异常。

非阻塞IO

多路复用IO

信号驱动IO

异步IO

多路复用的 select、poll、epoll 实现

Java IO 模型 与Linux IO 模型的对应关系

同步、异步、阻塞、非阻塞

总结


文章作者: 陈尚
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 陈尚 !
评论