五种IO模型包括
- 阻塞IO
- 非阻塞IO
- 信号驱动IO
- IO多路转接
- 异步IO
在网络环境下,一般将IO分为两步 1.等待 2.数据拷贝
所以如果要想提高IO效率,需要降低等的时间
1.阻塞IO

阻塞IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据)时被阻塞
在linux下,默认情况下所有的IO接口(包括socket)都是阻塞的,不返回调用结果就让线程一直阻塞。
一个简单的改进方法:在服务端使用多线程(多进程)。
多线程(多进程)的目的是让每个连接都拥有独立的线程(进程),让任何一个连接的阻塞都影响不到其他连接
- 如果同时为较多客户机服务时,推荐多线程,因为线程的开销远小于进程
- 如果单个服务执行体需要消耗较大的CPU资源,例如进行大规模或长时间的数据运算或文件访问时,进程更安全
优点:简单,实时性高,响应及时无延迟
缺点:需要阻塞等待,性能差
2.非阻塞IO

非阻塞的recvfrom系统调用之后,进程并没有别阻塞,内核马上返回进程,如果数据没准备好,返回error,
进程在返回之后,可以处理其他业务,过会再发起recvfrom系统调用。采用轮询检查内核数据,直到数据准备好,再拷贝处理数据
优点:在等待时做了其他事,后台可以有多个任务同时进行
缺点:任务完成的响应延迟增大了,导致整体的数据吞吐量降低
3.IO多路转接
单个进程就可以同时处理多个网络连接的IO

以select为例,当用户进程调用select,那么整个进程会被阻塞,同时,kernel会监视所有的select负责的socket,
当任何一个数据准备好,select就会返回可读。然后再进行recvfrom系统调用。
select只负责等,recvfrom只负责拷贝,IO多路转接属于阻塞IO,但可以对多个文件描述符进行阻塞监听,所以比阻塞IO效率高
优点:系统开销小 ,系统不需要创建新的额外进程或线程,也不需要维护进程或线程的运行,降低了系统的维护工作,节省了系统资源。
缺点:将事件响应和事件探测夹杂在一起,一旦事件响应的执行体庞大,可能会导致其他事件的执行体得不到响应,降低了事件探测的及时性。
4.信号驱动IO

内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作
- 首先创建一个信号处理函数,进程继续运行不阻塞
- 当数据准备好时,进程会受到一个SIGIO信号
- 在信号处理函数中调用IO操作函数处理数据报
缺点:回调机制、实现、开发应用难度大
5.异步IO

内核不在使用read和write的系统接口,而应用工程序调用aio_XXX系列的内核接口
- 当应用程序调用air_read的时候,内核一方面去取数据报内容,另一方面将程序控制权还给应用进程,进程继续执行
- 应用进程继续处理其他事物(应用进程是一种非阻塞状态)
- 当内核的数据报就绪的时候,由内核将数据报拷贝到应用进程中,返回aio_read中定义好的函数处理程序
阻塞IO和非阻塞IO的区别
- 阻塞是指调用结果返回之前,当前进程会被挂起,调用进程只有在得到结果才会返回
- 非阻塞调用指不能立刻得到结果,该调用不会阻塞当前进程
信号驱动式IO和异步IO的区别
- 信号驱动IO是由内核通知我们何时可以启动一个IO操作、这个IO操作由用户自定义的信号函数来实现
- 异步IO意味着通知内核启动某个IO操作、并让内核在整个操作(包括数据从内核复制到用户缓冲区)完成时通知我们,也就是说,异步IO是由内核通知我们IO操作何时完成、即实际的IO操作也是异步的
同步IO和异步IO区别
- 同步IO主动的调用recvfrom来将数据拷贝到用户内存
- 异步IO就像是用户进程将整个IO操作交给了内核完成,然后内核做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。

浙公网安备 33010602011771号