参考自: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访问,一般会有等待数据+数据从内存拷贝到进程。
我们先看下下面要讲的内容的图,看不懂不要紧。
同步阻塞IO(顺序执行,同步模型):
例子:跟朋友点餐后,只能坐餐厅等上菜,吃完才能走。
该IO是最常用IO,默认linux所有socket都是阻塞的
注:以上等待数据,内核复制阶段都会被锁住阻塞。
优缺点:无延迟返回数据,方便内核开发者;但是性能代价大。
同步非阻塞IO(顺序执行,同步模型)
跑回来问了很多次,有饭吃才坐下吃完饭走。
轮询
注:在等待数据 阶段read操作会返回error表当前阶段未完成(可轮询),数据内核复制阶段进程阻塞(不可轮询,阻塞中...)。
优缺点:等待完成时间可处理其他任务进程。但由于需要不断轮询请求,会导致数据吞吐量降低。
IO多路复用(顺序执行,同步模型)
借助app(帮忙的)观看上餐情况,偶尔看一下,做完回去吃即可。
注:与上面类似,不过可对多个IO端口进行监听,当其中一个socket准备好,返回进行可读(不需要等待接收到全部才处理,边接收部分数据边处理)。一般使用的是select,poll,epoll函数处理,就是通过epoll这种进程同时等待IO文件描述符,监听其fd状态,是就绪就返回。
IO多路复用在阻塞到select阶段时,用户进程是 主动 等待并调用select函数获取数据就绪状态消息,并且其进程状态为阻塞 。所以, 把IO多路复用归为同步阻塞模式 。
信号驱动IO:
用的不多,不做分析
异步非阻塞IO:
例子:叫外卖,外卖到了就叫你去拿,等待过程想干嘛就干嘛
异步IO非顺序执行
注:在等待数据,数据复制到用户空间两个IO阶段均非阻塞,完成后回调/发signal通知已完成.。
异步阻塞IO:
例子:逻辑上需要做完一件事在做另一件事,如请求数据时,先连接数据库再接收用户HTTP请求。
例子请查nodejs。
这是来再看一次下面的图:
总结:同步非阻塞虽然有部分不回锁住,但是相比异步的不需要做任何检查, 只要等回调响应还是差太远了。