参考自:https://www.jianshu.com/p/486b0965c296

首先解释下以下知识:

内核空间+用户空间。

进程切换是将当前进程状态更新保存在PCB,然后切换到另一个进程,也同时更新PCB,更新内存管理,恢复处理及上下文。( 处理及状态保存)

③进程阻塞:拥有CPU的运行态进程切换到阻塞状态。

索引内核为进程维护的文件记录表。

先拷到内核空间,再到应用程序地址空间。(频繁拷贝带给CPU,内存大负担)

Linux IO模型:

同步模型(synchronous IO)


    阻塞IO(bloking IO)


    非阻塞IO(non-blocking IO)


    多路复用IO(multiplexing IO)


,信号驱动式IO(signal-driven IO)


异步IO(asynchronous IO)

对于一次io访问,一般会有等待数据+数据从内存拷贝到进程。

我们先看下下面要讲的内容的图,看不懂不要紧。


Linux五种IO模型_非阻塞


同步阻塞IO(顺序执行,同步模型):

例子:跟朋友点餐后,只能坐餐厅等上菜,吃完才能走。

该IO是最常用IO,默认linux所有socket都是阻塞的


Linux五种IO模型_数据_02


注:以上等待数据,内核复制阶段都会被锁住阻塞。

优缺点:无延迟返回数据,方便内核开发者;但是性能代价大。

同步非阻塞IO(顺序执行,同步模型)

跑回来问了很多次,有饭吃才坐下吃完饭走。

轮询


Linux五种IO模型_多路复用_03


注:在等待数据 阶段read操作会返回error表当前阶段未完成(可轮询),数据内核复制阶段进程阻塞(不可轮询,阻塞中...)。

优缺点:等待完成时间可处理其他任务进程。但由于需要不断轮询请求,会导致数据吞吐量降低。

  IO多路复用(顺序执行,同步模型)

借助app(帮忙的)观看上餐情况,偶尔看一下,做完回去吃即可。


Linux五种IO模型_数据_04


注:与上面类似,不过可对多个IO端口进行监听,当其中一个socket准备好,返回进行可读(不需要等待接收到全部才处理,边接收部分数据边处理)。一般使用的是select,poll,epoll函数处理,就是通过epoll这种进程同时等待IO文件描述符,监听其fd状态,是就绪就返回。

IO多路复用在阻塞到select阶段时,用户进程是 主动 等待并调用select函数获取数据就绪状态消息,并且其进程状态为阻塞 。所以, 把IO多路复用归为同步阻塞模式 。

信号驱动IO:

用的不多,不做分析


Linux五种IO模型_非阻塞_05


异步非阻塞IO:

例子:叫外卖,外卖到了就叫你去拿,等待过程想干嘛就干嘛

异步IO非顺序执行


Linux五种IO模型_数据_06


注:在等待数据,数据复制到用户空间两个IO阶段均非阻塞,完成后回调/发signal通知已完成.。

异步阻塞IO:

例子:逻辑上需要做完一件事在做另一件事,如请求数据时,先连接数据库再接收用户HTTP请求。

例子请查nodejs。

这是来再看一次下面的图:


Linux五种IO模型_数据_07


总结:同步非阻塞虽然有部分不回锁住,但是相比异步的不需要做任何检查, 只要等回调响应还是差太远了。