网络编程中同步与异步,IO阻塞与非阻塞总结

IO操作分两个阶段

第1个阶段:等待数据准备好(从外部设备磁盘或网络读到内核缓冲区);
第2个阶段:采用系统调用(内核进程),操作系统内核将数据从内核缓冲区读到用户空间。
第1阶段花费的时间远远大于第2阶段

在这里插入图片描述

这两个阶段就会产生4种运行方式

  • 最好的proactor 异步非阻塞
    网络编程中同步与异步,IO阻塞与非阻塞总结_第1张图片
    首先异步中一定没阻塞方式处理;内核会主动通知一次
    同步阻塞IO
    网络编程中同步与异步,IO阻塞与非阻塞总结_第2张图片
    内核一般不会通知,只能轮询检测内核区是否有数据,有数据则才会去读取请求的回复

reactor 同步非阻塞IO
网络编程中同步与异步,IO阻塞与非阻塞总结_第3张图片

epoll内核会通知数据是否到了内核

在IO过程中,第1阶段到第2阶段分开情况下,又会存在内核主不主动通知用户进程数据IO可读问题,不通知,用户进程只能轮询检查是否有数据到了,如果主动通知那用户进程只需要去查看通知是否有IO可读。

通知:内核通知用户进程是否IO可读可写(一般只通知一次)
第1种情况
一般会发生在第1阶段与第2阶段之间,这种情况发生后一般不会有第2次通知
第2种情况
内核处理第2阶段结束时通知(这种情况下一般发生在第1种情况不通知的情况下)

Reactor
事件处理是异步的
I/O处理是同步的
I处理指的是从内核空间(或外部设备)读数据到用户空间内存过程
这个过程不论读取成功还是失败,都是需要时间的,也即上面网络事件的第2阶段
在线程中,若只有第2阶段执行完成后(无论成功失败都是执行一次完成)才能执行下一条用户指令,那么就是同步的。
而若发起请求注册后马上执行下一条用户指令,其他操作交由回调函数处理,不占用用户时间,用户可以在第2阶段干其他事情,则是异步的。

Reactor采用I/O多路复用技术,其第1阶段并没有占用时间,管理检测事件交由内核去完成了,而是注册后直接处理其他事情了(注册不需要用户态和内核态切换,基本不花费事件),而第2阶段read函数(需要用户态和内核态切换)占用了线程时间,故是同步I/O,由于可能有多个IO事件,而采用了IO多路复用技术。若IO变成了异步,那么就不会在用户进程使用IO多路复用技术了。

IO阻塞和非阻塞与异步与同步不是同一个概念。
阻塞一定是同步的,非阻塞可能是同步的,也可能是异步的,重点在于系统调用过程是否占用用户线程时间。

四种情况:

阻塞IO(同步)

跑去通知你去完成一件事,你不在,我一直等待,直到你回来了,然后我一直等待你完成后我才返回去干下一件事

非阻塞IO(+同步)

跑去通知你去完成,若你不在,我返回去干一会儿其他事情,然后轮询跑过来几次找你,直到你回来了,然后我一直等待你完成后我才返回去干下一件事

非阻塞IO(+同步) + 多路复用技术(管家,epoll) = reactor

我去找一个管家,给它说我要找你完成一件事,然后我去干其他事情了,当管家发现你在家时,管家就来通知我你在家了,然后我才跑去找你,这样不用轮询来找你了,然后我一直等待你完成后我才返回去干下一件事。

非阻塞IO(+异步)

我去找一个管家,给它说我要找你完成一件事,然后我去干其他事情了,当管家发现你在家时,然后管家找到你之后告诉你帮我完成那件事帮送到我屋头。
这里其实不需要管家,我只需要打个电话给你,你帮我完成事后通知我一下就行。

文章参考与<零声教育>的C/C++linux服务期高级架构系统教程学习:

服务器高级架构体系:https://ke.qq.com/course/417774?flowToken=1010783
音视频开发体系:https://ke.qq.com/course/3202131?flowToken=1040744
dpdk系统学习:https://ke.qq.com/course/5066203?flowToken=1043154
内核系统学习:https://ke.qq.com/course/4032547?flowToken=1042705
golang云原生体系:https://ke.qq.com/course/422970?flowToken=1043281

你可能感兴趣的:(Linux,C/C++,网络,linux,服务器)