五种IO模型

news/2024/11/19 12:15:50/

本文分享的是理解五种IO模型的基本概念, 重点是IO多路转接。

什么是IO

其实我们在读写数据的时候,比如使用了write、read、recv、send等等函数,本质是对数据的拷贝。即在写的时候,将数据拷贝到了TCP协议的发送缓冲区中。在读的时候,将接收到的数据先拷贝到接收缓冲区中。

那么在读写的时候,等待是离不开的环节。因此,我们可以这样理解IO:

IO = 等待 + 拷贝数据

而对于我们研究IO的时候,其实最主要最多的话题,都是在对“等待”做研究或者是等待的方式。

既然IO是等待+拷贝数据,那么高效IO的本质,就是需要减少等待在单位时间内的比重!

五种IO模型概念

我将用钓鱼作为例子,通俗地介绍五种IO模型是哪五种。

阻塞IO

有一天,张三来到鱼塘边钓鱼,张三把钓鱼的准备工作做好之后,就一直在那坐着,盯着鱼漂,啥也不去干,就一直在那盯着,直到鱼儿上钩,就拉钩成功钓到鱼。张三这种行为,换在IO中,便是阻塞IO。

阻塞IO:在内核将数据准备好之前, 系统调用会一直等待。所有的套接字, 默认都是阻塞方式。

阻塞IO是最常见的IO模型。

非阻塞IO

过一会儿,一个叫李四的人也来钓鱼了。李四跟张三的钓鱼方式不一样,李四没有一直盯着看,而是在等鱼儿上钩的期间,一会看看书,一会刷刷视频等等,然后过一会看看鱼漂有没有动静,如果没有,那么又转头去做别的事情。直到鱼儿上钩。李四这种行为,换在IO中就叫做非阻塞IO。

非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询。这对CPU来说是较大的浪费, 一般只有特定场景下才使用。

非阻塞IO: 如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码。

信号驱动

又过一会,一个叫王五的人也来钓鱼了,王五是一个聪明人,他将一个铃铛挂在鱼线上(假设没有其它外界影响使得铃铛响),然后在等待鱼上钩的期间,王五不会去主动看看鱼漂有没有动静,而是一直去看别的事情,直到铃铛响起,王五就知道鱼儿上钩了!王五这种行为,就是IO信号驱动。

信号驱动IO: 内核将数据准备好的时候, 使用SIGIO信号通知应用程序进行IO操作。

 

多路转接

再过一会,一个叫赵六的人也来钓鱼了。赵六带来了一百根鱼竿,同时用来钓鱼!等待鱼儿上钩期间,赵六跟张三的阻塞IO类似,只不过,赵六的一百根鱼竿,能够极大地提高钓鱼效率!赵六这个行为,就是IO多路转接。

IO多路转接: 虽然从流程图上看起来和阻塞IO类似. 实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态。

在IO多路转接中,使用系统调用select来进行等待,使用recvfrom来进行拷贝数据。

 以上四种方法都属于同步IO。

异步IO

此时一个叫田七的人路过鱼塘,看见那么多人在钓鱼,他就很想吃鱼了,但是他不想钓,于是他喊他的助手小明去帮他钓,田七给了小明一个装鱼的桶子,并告诉小明:“你钓完鱼了就跟我说,就把桶子给我吧!”。然后小明就去钓鱼了,田七就暂时离开,即不负责钓鱼的等待操作,也不负责把鱼钓上来的操作。田七这种行为,便是异步IO。

异步IO: 由内核在数据拷贝完成时, 通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。

同步IO和异步IO

同步和异步关注的是消息通信机制。

所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回. 但是一旦调用返回,就得到返回值了。换句话说,就是由调用者主动等待这个调用的结果。

异步则是相反, 调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后, 被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

就拿上述的五种IO模型来讲,前四种,不管是谁,起码都有等待或者把鱼钓上来这两个操作的其中之一,即参与了就属于同步。而在异步IO中,不管是等待还是执行操作,都没有参与。

另外,我们需要区分这里的同步与异步,同步与互斥。

同步与异步是消息通信的,而同步与互斥是进程/线程的制约关系。因此,我们在看到同步的时候,需要区分是同步通信异步通信的同步, 还是同步与互斥的同步。
 


http://www.ppmy.cn/news/98582.html

相关文章

Linux|奇怪的知识|一次性任务at命令的使用

前言: at命令是Linux的一个专有命令,该命令是旧的计划任务atd服务的客户端命令(at命令是c/s形式的软件套件里的client,客户端),主要的用处就是灵活制定一个工作计划,特定时间自动完成你所设定的…

springboot缓存

1. 认识缓存 一级缓存 - 缓存是一种介于数据永久存储介质与数据应用之间的数据临时存储介质 - 使用缓存可以有效的减少低速数据读取过程的次数,提高系统性能 Service public class BookServiceImplCache implements BookService {Autowiredprivate BookDao book…

数据结构之线性表(bsd, sys/queue.h)

数据结构之线性表 Author:Once Day Date:2023年5月27日 参考文档: Linux内嵌链表(sys/queue.h)详解_tissar的博客-CSDN博客嵌入式大杂烩周记第 3 期:sys/queue.h - 知乎 (zhihu.com)queue(7) - Linux manual page (man7.org)queue(3) - Op…

Pytest运行指定的case,这个方法真的很高效……

Pytest运行指定的case 在测试工作中,当我们写了较多的cases时,如果每次都要全部运行一遍,无疑是很浪费时间的,而且效率低下。 但是有一种方法可以帮助你快速地运行指定的测试用例,提高测试效率,那就是使用…

myql的三种删除方式:delete truncate drop

前言 在 MySQL 中,删除的方法总共有 3 种:delete、truncate、drop,而三者的用法和使用场景又完全不同,接下来我们具体来看。 1.delete detele 可用于删除表的部分或所有数据,它的使用语法如下: delete …

深度学习之卷积神经网络(CNN)

大家好,我是带我去滑雪! 卷积神经网络(Convolutional Neural Network,CNN)是一种基于深度学习的前馈神经网络,主要用于图像和视频识别、分类、分割和标注等计算机视觉任务。它主要由卷积层、池化层、全连接…

软件设计师第4题

首先,我是备考2023年上半年的考试。 一、历年考试题 历年的考题如下,从表中分析可以看出,动态规划法、排序算法、回溯法、分治法是很大概率考察的算法,尤其是动态规划法,本身其理解难度较高,且可以出的题型…

kvm虚拟机的克隆以及快照

一、克隆(常见有3种方法) 1 直接克隆(克隆虚拟机使用自己的磁盘) virt-clone -o vm-01 -n vm-02 -f /kvm/os/vm-02.qcow2 virsh start vm-02         #启动虚拟机后,修改