五种IO模型:阻塞/非阻塞/复用/信号驱动/异步IO模型
1. IO基本概念
1.1 IO概念
IO (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作
1.2 IO的两个阶段
LINUX中进程无法直接操作I/O设备(硬盘,打印机,显示器等),其必须通过系统调用请求kernel来协助完成I/O动作;内核会为每个I/O设备维护一个缓冲区。
所以,通常用户进程中的一个完整IO分为两阶段:用户进程空间<–>内核空间、内核空间<–>设备空间(磁盘、网络等)。
1.2.1 IO的两个阶段-例子说明
- 内核会为每个I/O设备维护一个缓冲区。
- 对于一个输入操作来说,进程IO系统调用后,内核会先看缓冲区中有没有相应的缓存数据,没有的话再到设备中读取,
因为设备IO一般速度较慢,需要等待;内核缓冲区有数据则直接复制到进程空间。 - 所以,对于一个网络输入操作通常包括两个不同阶段:
(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 典型应用和特点:
-
阻塞socket
-
特点:
进程阻塞挂起不消耗CPU资源,及时响应每个操作;
实现难度低、开发应用较容易;
适用并发量小的网络应用开发; -
缺点:
不适用并发量大的应用:因为一个请求IO会阻塞进程,所以,得为每请求分配一个处理进程(线程)以及时响应,系统开销大。
2.2 非阻塞IO模型
2.2.1 举例子说明:非阻塞IO模型
假设你正在和美女微信聊天,消息发过去后,等待她回复。在等的时候你可以做其他事情,去烧水,洗衣服等。
你做其他事情的时候,每个一会就看看手机,看她是否发消息过来了。
你每次看手机都是一次轮询的过程。
2.2.2 非阻塞IO模型
进程发起IO系统调用后,如果内核缓冲区没有数据,需要到IO设备中读取,进程返回一个错误而不会被阻塞;进程发起IO系统调用后,如果内核缓冲区有数据,内核就会把数据返回进程。
2.2.3 典型应用和特点:
- 典型应用:socket是非阻塞的方式(设置为NONBLOCK)
- 特点:
进程轮询(重复)调用,消耗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 典型应用和特点:
-
典型应用:select、poll、epoll三种方案
-
特点:
专一进程解决多个进程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系统支持
- 典型应用:JAVA7 AIO、高性能服务器应用
- 特点:
不阻塞,数据一步到位
需要操作系统的底层支持,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://blog.csdn.net/tjiyu/article/details/52959418
https://blog.csdn.net/ZWE7616175/article/details/80591587