网络编程 IO模型 :阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO


IO模型

根据各自的特性不一样,IO模型被分为阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO五类。
最主要的两个区别就是阻塞与非阻塞,同步与异步web

阻塞与非阻塞

阻塞与非阻塞最主要的区别就是程序在等待调用结果时的状态。异步

阻塞:为了完成一个功能发起调用,若是不具有完成功能的条件,则调用会一直等待
非阻塞:为了完成一个功能发起调用,若是不具有完成功能的条件,则当即报错返回svg

同步与异步

同步与异步最主要的区别就是功能完成的流程是不是顺序化的,且完成的是自身仍是系统。函数

同步:功能完成的流程是顺序化的,而且功能由自身完成。
异步:功能完成的流程是不肯定的,而且功能由系统完成。spa


阻塞IO

发起IO调用,若是不具有IO条件,则一直等待直到条件就绪。操作系统

在这里插入图片描述

优势流程以及代码实现都很是简单,任务顺序操做3d

缺点任务处理效率较低,没法充分利用资源code


非阻塞IO

发起一个IO调用,若是不具有IO条件,则当即报错返回,继续执行其余命令。经过一个循环来不断发起IO请求,直到条件就绪。xml

在这里插入图片描述

优势:与阻塞IO相比较来讲,利用了等待的时间去作了其余的事情,对资源的利用更加充分blog

缺点:与阻塞IO对比,IO调用须要循环发起,流程更加复杂。而且若是IO条件就绪了,也要等待上一轮循环结束后进入当前循环,才能进行处理,这就致使了IO不够实时

非阻塞IO能够经过fcntl函数设置描述符状态来实现
例如:

void SetNoBlock(int fd) 
{
	int flag = fcntl(fd, F_GETFL, 0);
	
	flag |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flag);
}

信号驱动IO

自定义一个IO就绪的信号,当IO就绪时就发出这个信号。在没有收到信号时,能够继续处理其余事情,一旦收到信号,就会中断当前操做,来优先处理IO事件。
在这里插入图片描述
优势:相较于非阻塞IO,由于信号到来后就直接强行中断进行处理,更加实时。而且在没收到信号的时候能够执行其余工做,资源利用更加充分

缺点:由于须要自定义信号,又要有主控流程也要有信号处理流程,而且还须要考虑信号是否可靠致使的事件丢失状况,流程会更加的复杂


多路复用IO

用于对大量的IO事件进行监控,可以让用户只针对就绪了指定事件(可读、可写、异常) 的IO进行IO操做。只针对就绪的描述符进行操做,避免了阻塞,而且提升了效率。

在Linux下,操做系统提供了三种模型:select模型、poll模型、epoll模型。这三种模型的具体使用以及细节会放到下一篇博客中
在这里插入图片描述
根据不一样的模型具体的优缺点也不同。


异步IO

IO处理的顺序不肯定,整个IO的过程(等待 + 数据拷贝)由操做系统来完成而并不是用户。
在这里插入图片描述
流程

  1. 自定义一个IO完成信号
  2. 发起异步调用后返回,此时用户能够继续处理其余事情
  3. 系统进行IO事件的等待以及数据拷贝
  4. IO完成后经过信号通知进程IO

优势:对资源的利用最为充分, 以最高的效率进行任务的处理
缺点:资源消耗较高, 流程最为复杂

上面的五种IO模型,从前日后处理的效率逐渐增长,对资源的利用也增长充分,可是流程也愈来愈复杂。