5种网络I/O模型

2 篇文章 0 订阅

待编辑中…

一、前言

在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO(blocking IO)、非阻塞IO(nonblocking IO)、多路复用IO(IO multiplexing)、信号驱动IO(signal driven IO)以及异步IO(asynchronous IO)。

IO发生时涉及到的对象和步骤:

  1. 对于网络IO而言(以read操作为例),涉及到的两个对象:用户进程(或者线程)和 系统内核。
  2. 当read操作发生时,它会经历两个阶段:
    1)等待数据准备(Waiting for the data to be ready)
    2)将数据从内核拷贝到用户进程中(Copying the data from the kernel to the process)
    这两点很重要,因为这些IO模型的主要区别在这两个阶段各有不同。

二、五种网络IO模型

1. BIO

1.1. 定义/概念

当用户程序中发起read操作(即底层的recvfrom系统调用)后,内核进入第一个阶段,即等待数据就绪,而用户程序线程则被阻塞住。当数据准备就绪后,则内核将数据拷贝到用户程序缓冲区中并返回结果(或者发生错误时才返回结果),用户进程才解除阻塞状态。IO执行的两个阶段(等待数据和拷贝数据)用户线程都被阻塞住了。
在这里插入图片描述

1.2. 优/缺点

每连接每线程。连接少的情况下表现良好,但高并发情况下,创建的线程很多而导致资源消耗和性能降低。
主要问题:
1)线程资源受限:线程是操作系统中非常宝贵的资源,同一时刻有大量的线程处于阻塞状态是非常严重的资源浪费,操作系统耗不起。
2)线程切换效率低下:频繁进行线程切换(包括保护现场和恢复现场等操作),使应用性能急剧下降。
3)以字节流为单位,效率不高。
(关于线程资源受限的优化:
可以通过伪异步方式优化:即服务端维护线程池,将请求由其中的线程处理,但达到一定并发上限后,性能也会达到其瓶颈。)
为了解决这三个问题,JDK在1.4之后提出了NIO。


2. NIO

2.1. 定义/概念

从用户程序中发起read操作(即底层的recvfrom系统调用)后,用户程序不需要等待,而立即收到一个结果,一般用户程序中轮询检查这个结果状态,如果是个error(EWOULDBLOCK),则表明内核中数据还没准备好,于是再次发送read操作。而内核中一旦数据准备就绪又再次收到用户请求,则内核将数据拷贝到用户缓存区中并返回OK。
在这里插入图片描述

2.2. 优/缺点

非阻塞IO中,用户程序通过死循环不断询问内核是否数据准备就绪,即用户线程不会释放CPU执行权限,而导致CPU占用率升高!因此一般情况下很少使用循环方式来读取数据。


3. 多路复用IO

3.1. 定义/概念

从用户程序中发起.。。。
在这里插入图片描述

3.2. 优/缺点


4. 异步IO

4.1. 定义/概念

从用户程序中发起.。。。
在这里插入图片描述

4.2. 优/缺点


5. 异步IO

5.1. 定义/概念

从用户程序中发起.。。。
在这里插入图片描述

5.2. 优/缺点


三、参考

聊聊Linux 五种IO模型
Java NIO1:I/O模型概述
五种IO模型详解
5种网络IO模型(有图,很清楚)
NIO概述
《跟闪电侠学Netty》开篇:Netty是什么?

附:

  1. Linux文件描述符的理解:
struct files_struct {
  /*
   * read mostly part
   */
	atomic_t count;
	struct fdtable __rcu *fdt;
	struct fdtable fdtab;
  /*
   * written part on a separate cache line in SMP
   */
	spinlock_t file_lock ____cacheline_aligned_in_smp;
	int next_fd;
	struct embedded_fd_set close_on_exec_init;
	struct embedded_fd_set open_fds_init;
	struct file __rcu * fd_array[NR_OPEN_DEFAULT]; //进程级打开文件描述符表
};

打开文件描述符表:实际上就是files_struct 中的成员struct file * fd_array[NR_OPEN_DEFAULT]它是一个指针数组,数组每一个元素都是一个指向file类型的指针,可想而知,这些指针都会指向一个打开的文件,并且file这一数据结构就是用来描述一个打开的文件的,而我们所说的文件描述符,实际上就是这个指针数组的索引。这也是为什么文件描述符是非负整数。

参考:
Linux文件描述符的理解

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值