五种IO模型:阻塞/非阻塞/复用/信号驱动/异步IO模型

本文详细介绍了IO的基本概念和五个模型:阻塞IO、非阻塞IO、IO复用、信号驱动IO和异步IO。通过实例解释了各模型的工作原理及特点,对比了同步与异步IO的区别,帮助读者深入理解IO在系统层面上的处理方式及其在不同场景下的应用选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. IO基本概念

1.1 IO概念

IO (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作

1.2 IO的两个阶段

LINUX中进程无法直接操作I/O设备(硬盘,打印机,显示器等),其必须通过系统调用请求kernel来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。
所以,通常用户进程中的一个完整IO分为两阶段:用户进程空间<–>内核空间、内核空间<–>设备空间(磁盘、网络等)。

1.2.1 IO的两个阶段-例子说明

  1. 内核会为每个I/O设备维护一个缓冲区。
  2. 对于一个输入操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,
    因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。
  3. 所以,对于一个网络输入操作通常包括两个不同阶段:

(1)等待网络数据到达网卡→读取到内核缓冲区,数据准备好;
(2)从内核缓冲区复制数据到进程空间。

1.2 IO种类

IO有内存IO、网络IO和磁盘IO三种,通常我们说的IO指的是后两者。

2. 五种IO模型

五种IO模型包括:阻塞IO模型、非阻塞IO模型、IO复用模型、信号驱动的IO模型、异步IO模型。其中,前四个被称为同步IO。

2.1 阻塞IO模型

2.1.1 举例子说明:阻塞IO模型

假设你正在和美女微信聊天,消息发过去后,等待她回复。在等的时候不做其他的事情,十分专心。直到她回复了,你才安心做其他事情。

2.1.2 阻塞IO模型

进程发起IO系统调用后,进程被阻塞,转到内核空间处理,整个IO处理完毕后返回进程。操作成功则进程获取到数据。

2.1.3 典型应用和特点:

  1. 阻塞socket

  2. 特点:
    进程阻塞挂起不消耗CPU资源,及时响应每个操作;
    实现难度低、开发应用较容易;
    适用并发量小的网络应用开发;

  3. 缺点:
    不适用并发量大的应用:因为一个请求IO会阻塞进程,所以,得为每请求分配一个处理进程(线程)以及时响应,系统开销大。

2.2 非阻塞IO模型

2.2.1 举例子说明:非阻塞IO模型

假设你正在和美女微信聊天,消息发过去后,等待她回复。在等的时候你可以做其他事情,去烧水,洗衣服等。
你做其他事情的时候,每个一会就看看手机,看她是否发消息过来了。
你每次看手机都是一次轮询的过程。

2.2.2 非阻塞IO模型

进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞;进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。

2.2.3 典型应用和特点:

  1. 典型应用:socket是非阻塞的方式(设置为NONBLOCK)
  2. 特点:
    进程轮询(重复)调用,消耗CPU的资源;
    实现难度低、开发应用相对阻塞IO模式较难;
    适用并发量较小、且不需要及时响应的网络应用开发;

2.3 IO复用模型

2.3.1 举例子说明:IO复用模型

假设你正在和很多,很多美女微信聊天(虽然不太好),消息发过去后,等待她,no 是她们回复。
你一次能看很多美女聊天框是否有哪个消息来了。如美女n消息来了,它会通过信号(顶顶顶)通知你。
增加了效率,减少了等待的时间。

2.3.2 IO复用模型

多个的进程的IO可以注册到一个复用器(select/poll/epoll)上,然后用一个进程调用该select/poll/epoll, select/poll/epoll会监听所有注册进来的IO;

如果select没有监听的IO在内核缓冲区都没有可读数据,select调用进程会被阻塞;而当任一IO在内核缓冲区中有可数据时,select调用就会返回;

而后select调用进程可以自己或通知另外的进程(注册进程)来再次发起读取IO,读取内核中准备好的数据。

可以看到,多个进程注册IO后,只有另一个select调用进程被阻塞。

2.3.3 典型应用和特点:

  1. 典型应用:select、poll、epoll三种方案

  2. 特点:
    专一进程解决多个进程IO的阻塞问题,性能好
    实现、开发应用难度较大;
    适用高并发服务应用开发:一个进程(线程)响应多个请求

2.4 信号驱动的IO模型

2.4.1 举例子说明:信号驱动的IO模型

假设你正在和美女微信聊天,消息发过去后,等待她回复。这时你不用傻等,把手机调整成响铃,并且声音最大就可以了。
微信消息来了,它会通过信号(顶顶顶)通知你,你就知道了。

2.4.2 信号驱动的IO模型

当进程发起一个IO操作,会向内核注册一个信号处理函数,然后进程返回不阻塞;
当内核数据就绪时会发送一个信号给进程,进程便在信号处理函数中调用IO读取数据。

2.4.3 典型应用和特点:

特点:回调机制,实现、开发应用难度大;

2.5 异步IO模型

2.5.1 举例子说明:异步IO模型

假设你正在和很多,很多美女微信聊天(虽然不太好),但是很多人聊天太耽误事,你就雇佣了一个小白替你跟美女们聊天。
有美女同意一起约会就通知你,你强势登场……balabala

2.5.2 异步IO模型

当进程发起一个IO操作,内核一方面去取数据报内容返回,另一方面将程序控制权还给应用进程,应用进程继续处理其他事情,是一种非阻塞的状态。
当内核中有数据报就绪时,由内核将数据报拷贝到应用程序中,让其处理。

2.5.3 典型应用和特点:

很少有Linux系统支持

  1. 典型应用:JAVA7 AIO、高性能服务器应用
  2. 特点:
    不阻塞,数据一步到位
    需要操作系统的底层支持,LINUX 2.5 版本内核首现,2.6 版本产品的内核标准特性;
    实现、开发应用难度大;
    非常适合高性能高并发应用;

3. 同步IO和异步IO

3.1 同步IO:导致请求进程阻塞,直到I/O操作完成。

用户进程发出IO调用,去获取IO设备数据,双方的数据要经过内核缓冲区同步,完全准备好后,再复制返回到用户进程。
而复制返回到用户进程会导致请求进程阻塞,直到I/O操作完成。

3.2 异步IO:不导致请求进程阻塞。

用户进程发出IO调用,去获取IO设备数据,并不需要同步,内核直接复制到进程,整个过程不导致请求进程阻塞。

4. 模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL

参考:https://www.cnblogs.com/nufangrensheng/archive/2013/03/10/2952658.html

参考:

https://blog.csdn.net/tjiyu/article/details/52959418
https://blog.csdn.net/ZWE7616175/article/details/80591587

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值