5种IO模型

引言

在之后的多篇文章里面我会介绍陈硕老师的网络库,并且用c++20的方式重写一遍网络库的主干代码。所以在这一篇文章里面主要总结一些必备的知识,也就是linux系统编程的一些关键。

阻塞和非阻塞

在数据准备的时候,也就是监听状态的时候,我们有两种状态:一种是阻塞,一种是非阻塞。

阻塞指的是接受数据的时候并不会一直轮询,当有数据来的时候会自动解除阻塞,recv就是这种类型,而非阻塞指的是通过while()循环,可以得到CPU的时间片的,并且会一直占用CPU的时间片。

我们举个例子 int size = recv(sockfd, buf, 1024, 0) ,当返回值是size > 0时,我们表示的是收到的字节数量。然后sockfd当我们设置成阻塞的情况下,size == 0时,表示断开了连接,size == -1时就是出现了错误,而当sockfd设置成非阻塞的情况下,size == -1 并且全局变量errno == EAGAIN的时候就是非阻塞的出错。

同步和非同步

当我们数据准备完成之后,我们就到了数据的读写。数据的读写分为同步和异步。我们先说同步:

数据来到了TCP的缓冲区,数据会被一个一个的读到buf1024里面,当数据读完之后才会返回给size,于是我们就可以接着往下执行代码。所以只要数据没有被读完,我们的代码就不会往下面走。

所以我们阻塞和非阻塞和同步和异步并没有一一对应的关系,比如我们的epoll就是同步IO,也是阻塞调用,epoll_wait()在调用的时候,最后一个参数时timeout,如果不自定义时间的话,相当于工作在阻塞的状态,当数据来到的时候,我们就会调用recv,这个操作肯定是我们自己在读,而不是操作系统在帮忙,所以是同步。

所以当recv没有读完的时候,我们就无法进行下面的代码

然后就是异步:

而异步的IO就是操作系统帮我们读到buf里面,而我们的应用程序可以执行其他的代码,当读完的时候我们就会发送给用户一个sigio的信号,这个时候就可以拿buf执行之后的代码了。

所以我们可以用一句话总结一下同步和异步的区别:在处理IO的时候,阻塞和非阻塞都是同步IO,而只有调用特殊API的时候才是异步。因为异步的读取数据是内核做的,所以必须要内核提供的API。

五种IO模型

一个典型的IO调用就是分为两个阶段,数据准备和数据读写,数据准备阶段就是阻塞和非阻塞,表现得状态就是阻塞等待或者直接返回(没有数据就直接返回,所以我们一般while()循环等待)。

而同步就是A向B发送一个网络IO接口时,数据的读还是写都是由A来完成(无论是阻塞还是非阻塞,而异步表示的是A向B发送网络IO接口,并且向B传入了事件和事件发生时的通知A的方式,A就可以处理其他的逻辑了。当B处理完事件之后,会按照之前原来约定的方式通知A。

阻塞

非阻塞

IO复用

我们的select/poll/epoll 系统调用,而epoll就可以实现一个线程监听多个fd,

信号驱动

其实和IO复用的作用差不多,就是先发送一个信号表示正在等待数据,当数据准备好了之后,就会发送给应用层表示数据来了,但是读取的工作还是应用层来做,也就是recv,所以这个也是同步,而不是异步。

异步

总结

本篇文章到这里就结束了,在之后的文章里面会介绍muduo网络库,希望可以帮助大家理解~~~

相关推荐
FreeTinker1 小时前
企业存储服务器NAS的选型逻辑与补充路径
运维·服务器
呱呱巨基1 小时前
Docker 基础概念学习
linux·c++·学习·docker
打妖妖灵滴哪吒1 小时前
OSI七层网络参考模型(图文版)
网络
acrel71 小时前
算力机房供电不间断,智能电力运维保驾护航
运维·安全·机房电力运维·机房配电·列头柜监测
mengpp_1234562 小时前
物联网云平台可以离线使用吗?摒弃云端依赖,工业现场离线自动化解决方案
运维·物联网·自动化·华为云
CodeJourney_J2 小时前
网络安全简述-加密技术
网络·安全·密码学
Acrellea2 小时前
ADL200W/ADL400W 导轨电表:一块小表终结光储防逆流之痛
运维·能源
xiaoxiangsiyan2 小时前
企业网络运维自动化与管理协议深度指南
linux·运维·服务器·网络·学习·自动化
郝学胜_神的一滴3 小时前
C++20 高级编程 001:从极简HelloWorld到现代类型体系全梳理
c++·后端