Java IO:网络IO模型

本文详细介绍了Java中的五种网络IO模型:阻塞式IO、非阻塞式IO、IO复用、信号驱动式IO和异步IO。通过对比分析各种模型的工作原理,阐述了它们在处理网络数据传输时的差异,特别是对进程阻塞、数据传输和CPU利用率的影响。同时,提到了epoll作为select/poll的增强版,解决了句柄数限制和效率问题。
摘要由CSDN通过智能技术生成

网络IO模型有5种,分别为:阻塞式IO,非阻塞式IO,IO复用,信号驱动式IO 和 异步IO


一.  操作系统如何处理IO

    Linux 会把所有的外部设备都看成一个文件来操作,对外部设备的操作可以看成是对文件的操作。我们对一个文件的读写,都会通过内核提供的系统调用,内核会给我们返回一个 File Descriptor,这个描述符是一个数字,指向内核的一个结构体,我们应用程序对文件的读写就是对描述符指向的结构体的读写

    系统调用是如何完成IO操作?Linux 会把内存分为 内核区和用户区。Linux 的内核区会帮我们管理所有的硬件资源,并且会提供系统调用,我们应用程序的读操作,就会通过系统调用 read 发起一个读操作,这个时候,内核就会创建一个文件描述符,通过驱动向硬件发送读指令,并且把读的数据放在描述符指向的结构体的缓冲区中。当这个数据传到用户区的时候,就完成了一次 IO。

    Linux 系统调用的 read,是一个阻塞函数。这个我们应用程序在发起read系统调用的时候,就必须要阻塞,进程挂起,等待文件描述符的读就绪。

    从上面我们可以知道,应用程序的一个 read系统调用,需要经过:

  1. 硬件读取文件数据到文件描述符指向的结构体的缓冲区。
  2. 结构体的缓冲区的数据 传输到 用户区。

二. 阻塞式 IO

    在进行网络IO的时候,进程发起一个 recvform 系统调用,然后进程就会被阻塞,什么也不干,等待上述 所说的 1 和 2步骤完成(也就是硬件读取内容到内核的结构体缓冲区,结构体缓冲区的内容到用户区),最后进程再被处理。大致如下图1:


图1


二. 非阻塞式 IO

    在上述的 阻塞式 IO中,可以看到,进程在发起了 recvform 系统调用的时候,就会阻塞,那么非阻塞式 IO 和 阻塞式 IO 的一个区别就在这里,它并不会阻塞,而是马上返回一个错误码,进程在得到错误码之后,可以干点别的事情,然后再重复上述的步骤,也就是又发起一个 recvform 系统调用。这个过程就成为轮询

    需要注意的是,上述的轮询只是针对操作系统处理IO的第一步,也就是 硬件读取数据到内核的结构体缓冲区,不针对第二步,也就是说,内核的结构体缓冲区的数据复制到用户区还是需要经过阻塞。如下图2:


图2


三. IO复用

    由上面的非阻塞式IO可以看出,轮询占了很大一部分过程,这个过程会消耗很多CPU时间。这个轮询是由用户区发起的,但是,这个轮询如果是由内核区发起的,那么效率就有提升。IO复用提供了两个 系统调用 :select 和 poll。select 系统调用是内核级别的,它和 非阻塞式的轮询 有一个区别,就是select 轮询 可以等待多个 socket,任何一个socket 的数据准备好了,那么就可以返回进行读。 select 和 poll调用之后,会阻塞进程,那么这种阻塞进程不同于 第一种 阻塞式IO的阻塞,此时的select不是等到socket数据全部到达后再处理,而是有一部分数据就会调用用户进程处理。打个比方:钓鱼的时候,雇佣一个帮手,他可以同事抛下多个鱼竿,任何一杆的鱼上钩,他就会拉杆,他只负责帮我们,不负责帮我们处理,所有我们还得在一边等着,等到他拉杆,我们再处理。 如下图3:


图3

Ps:实际上 select/poll 是落后的,因为 select 的句柄数有限,为1024 个,也就是说,同次检测 1025 个句柄死 是不可能。另外,内核的select是采用轮询的方法,select检测的句柄数越大就会越耗时,这些都是问题。那么epoll就能够解决这些问题,epoll 实际上也是 slect/poll 的增强版。



四. 信号驱动式IO

    也就是说,数据未准备就绪的时候,那么就进行等待,但是这个等待不会进行轮询,也不会阻塞。而是在某一时刻如果数据准备好了,那么内核会通知进程启动IO操作,将数据从内核区复制到用户区。如下图4 所示:


图4


五. 异步IO

    异步 IO 是指 相当于 信号式驱动 IO 的一个升级版本。异步 IO 是等 内核完成整个操作之后再通过应用程序,这整个过程包括了 硬件读取数据到 内核结构体的缓冲区中,以及缓冲区的数据复制到 用户区中,这整个过程进程都不会阻塞。如下图5:


图5


总结:以上就是 操作系统如何处理IO,以及常用的 5种 网络 IO模型。包括(阻塞式IO(java的传统IO),非阻塞式IO(NIO),多路复用IO,信号驱动IO,异步IO)


参考:

  1. 深入浅出异步IO模型
  2. 简明网络IO模型
  3. 《网络编程》IO模型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值