IO模型(Java)

io模型本是UNIX网络编程相关的内容。UNIX中IO模型有五种,包括阻塞 I/O、非阻塞 I/O、I/O 复用、信号驱动式 I/O 、异步 I/O 等。

 阻塞 I/O 模型

阻塞式IO模型,一般表现为进程或线程等待某个条件,如果条件不满足,则一直等下去。条件满足,则进行下一步操作。如下图:

非阻塞 I/O 模型

非阻塞式IO模型:进程或线程目的未达到时,不再一味的等着,而是直接返回。然后通过轮询的方式,不停的去问内核数据准备好没。如下图:

 

I/O 复用模型

Unix/Linux 环境下的 I/O 复用模型包含三组系统调用,分别是 select、poll 和 epoll(FreeBSD 中则为 kqueue)。select 出现的时间最早,在 BSD 4.2中被引入。poll 则是在 AT&T System V UNIX 版本中被引入(详情请参考 UNIX man-page)。epoll 出现在 Linux kernel 2.5.44 版本中,与之对应的 kqueue 调用则出现在 FreeBSD 4.1,早于 epoll。select 和 poll 出现的时间比较早,在当时也是比较先进的 I/O 模型了,满足了当时的需求。不过随着因特网用户的增长,C10K 问题出现。select 和 poll 已经不能满足需求了,研发更加高效的 I/O 模型迫在眉睫。到了 2000 年,FreeBSD 率先发布了 select、poll 的改进版 kqueue。Linux 平台则在 2002 年 2.5.44 中发布了 epoll。

select模式:select 有三个文件描述符集(readfds),分别是可读文件描述符集(writefds)、可写文件描述符集和异常文件描述符集(exceptfds)。应用程序可将某个 socket (文件描述符)设置到感兴趣的文件描述符集中,并调用 select 等待所感兴趣的事件发生。比如某个 socket 处于可读状态了,此时应用进程就可调用 recvfrom 函数把数据从内核空间拷贝到进程空间内,无需再等待内核准备数据了。如下图:

一般情况下,应用进程会将多个 socket 设置到感兴趣的文件描述符集中,并调用 select 等待所关注的事件(比如可读、可写)处于就绪状态。当某些 socket 处于就绪状态后,select 返回处于就绪状态的 sockct 数量。注意这里返回的是 socket 的数量,并不是具体的 socket。应用程序需要自己去确定哪些 socket 处于就绪状态了,确定之后即可进行后续操作。

 信号驱动式 I/O 模型

信号驱动式 I/O 模型是指,应用进程告诉内核,如果某个 socket 的某个事件发生时,请向我发一个信号。在收到信号后,信号对应的处理函数会进行后续处理。如下图:

异步 I/O 模型

异步 I/O 是指应用进程把文件描述符传给内核后,啥都不管了,完全由内核去操作这个文件描述符。内核完成相关操作后,会发信号告诉应用进程,某某 I/O 操作我完成了,你现在可以进行后续操作了。如下图:

上图通过 aio_read 把文件描述符、数据缓存空间,以及信号告诉内核,当文件描述符处于可读状态时,内核会亲自将数据从内核空间拷贝到应用进程指定的缓存空间呢。拷贝完在告诉进程 I/O 操作结束,就可以直接使用数据了。

几种IO模型的对比图:

对于java的IO(BIO NIO AIO)而言,以socket.read()为例子:

传统的BIO里面socket.read(),如果TCP RecvBuffer里没有数据,函数会一直阻塞,直到收到数据,返回读到的数据。

对于NIO,如果TCP RecvBuffer有数据,就把数据从网卡读到内存,并且返回给用户;反之则直接返回0,永远不会阻塞。

最新的AIO(Async I/O)里面会更进一步:不但等待就绪是非阻塞的,就连数据从网卡到内存的过程也是异步的。

换句话说,BIO里用户最关心“我要读”,NIO里用户最关心"我可以读了",在AIO模型里用户更需要关注的是“读完了”。

NIO一个重要的特点是:socket主要的读、写、注册和接收函数,在等待就绪阶段都是非阻塞的,真正的I/O操作是同步阻塞的(消耗CPU但性能非常高)。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值