5种IO模型详解(select、poll、poll)

news/2024/7/9 18:02:59 标签: golang, linux, epoll

五种I/O模型

  1. 同步阻塞IO模型(BlockIng IO)
  2. 同步非阻塞IO模型(Non-blockIng IO )
  3. 多路复用IO模型(IO Multiplexing )
  4. 异步IO(Asynchronous IO)
  5. 信号驱动IO模型

首先,我们需要明确几个基础概念:

同步:操作系统种的概念:是指必须在先行条件满足之后才能开始执行某一任务。在这里主要是指在触发了IO操作之后必须等待IO操作完成,才能执行接下来的任务。有同步阻塞和同步非阻塞之分。

异步:是指可以和某一个任务同时进行,互不干扰。在这里主要是指出发了IO操作后可以同时执行其他的任务。

阻塞:表示是否停滞在某一状态,无法进行其他操作。

非阻塞:开始某一任务后,可以进行其他操作,但需要定时询问此任务是否完成,也称为轮询。

同步阻塞IO模型(BlockIng IO)

image-20210920162904497

​ 从图中可以看出,同步阻塞模型中,线程在进行了系统调用之后,由于数据还没有准备好,此后一直处于内核态,直到数据准备完成并且从内核的缓冲区中拷贝到用户态的数据区中,系统才从内核才切换成用户态,才能继续执行下面处理数据的操作。

​ 显而易见,这样的方式,大量的时间都阻塞在了内核态中,等待数据的时间都被白白浪费掉了。大大降低了系统的吞吐量,影响系统的并发性。

同步非阻塞IO模型:(Non-blocking IO)

image-20210920164521060

​ 同步非阻塞IO模型和同步阻塞IO模型最大的区别在于在第一次进行了系统调用后,系统不会一直停留在内核态等待,而是立即切换为用户态,此后每隔一段时间就切换回内核态去查看数据是否准备完成,如果没有准备好则再次回到用户态执行其他操作,若事已经准备完成则进入数据拷贝阶段。

​ 可以看到,此时在等待数据到来的过程中,系统的时间已经不是被完全浪费的了,而是通过不断询问的方式来查看是否可以进行下一步操作了。效率虽然得到了提升,但在用户态和内核态之间频繁切换的花销过大,显然还是不够尽如人意。

IO多路复用模型(IO Multiplexing)。

image-20210920171951805

​ 首先需要明确的是,IO多路复用模型的select、poll、epoll都是同步IO,也就是说调用了这些方法之后,都需要等待某一事情发生后,才能继续后面的拷贝操作!

那么区别到底在哪里呢主要是在于多个IO事件都可以注册在同一个复用器(select、epoll)上,然后调用该方法后,系统就开始监听所有注册进来的IO事件,一旦有一个或者多个IO事件的数据准备完成后,便会促使复用器告知之前已经设置好的某一进程(或自己),进来完成后续的操作(比如本文中的拷贝数据)。

​ IO多路复用模型的主要优势在于可以用一个线程去处理多个IO事件。

而select、poll、epoll实现的区别究竟在哪里呢?

  • 当select复用器上注册的IO事件有一个或者多个满足了条件时,便会告知之前注册好的另一进程(或自己),但并没有告知具体是哪一个IO事件满足了条件,需要此线程自己去遍历注册的所有IO事件来寻找。
  • poll与select类似,区别在于select对于注册的IO事件的数量有限制,而poll没有此限制,但注册的事件数量过多时,性能明显下降。
  • epoll与前两者最大的区别在于,注册器会告诉相应的线程,究竟是哪个IO事件满足了条件,不需要再去遍历所有的IO事件。

信号驱动的IO事件

image-20210920173033792

​ 信号驱动的IO模型,当线程进行系统调用时发现IO事件的数据还没有准备好,则立即切换回用户态,等内核态中的数据准备好了之后,向用户线程发送一个信号,告知此时已经可以进行数据的拷贝了,用户线程再次执行系统调用,切换到内核态拷贝相应的数据,

异步IO模型 (Asynchronous IO)

image-20210920173147791

​ 异步模型不阻塞,等到对应的IO事件数据准备完成后,如果IO成功的话,会直接将IO的结果返回给进程。


http://www.niftyadmin.cn/n/1544516.html

相关文章

oracle补丁下载需要什么_Oracle 11g(11.2.0.4)补丁安装教程

1.将oracle11g升级到11.2.0.4(1)检查oracle当前版本:cmd命令提示符下运行“sqlplus -v”。如果版本号已经是11.2.0.4,则跳过此步骤,直接进入“2. 替换oracle目录下的OPATCH”。(2)解压oracle11.2.0.4的安装包,运行setup开始安装。…

深入理解redis之特性简介与性能测试工具redis-benchmark

什么是redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashe…

【数据结构】Java实现图的DFS和BFS

图的深度优先遍历(DFS)和广度优先遍历(BFS),DFS利用递归来实现比较易懂,DFS非递归就是将需要的递归的元素利用一个栈Stack来实现,以达到递归时候的顺序,而BFS则是利用一个队列Queue来实现。 package DataStructure;imp…

c语言斐波那契数列_40.细说递归之二:Python求解斐波那契数列

本篇通过青蛙跳台阶、兔子数列(斐波那契数列)问题进一步理解递归思想的魅力。上一篇最后的题目如下:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法?归纳推理方式不妨假设…

深入理解redis底层结构之SDS

SDS(Simple Dynamic String) ​ 即简单动态字符串,是redis自定义的数据结构。 ​ 首先介绍一下几个基本概念: 柔性数组:在结构体中最后一个成员允许是未知大小的数组,这就叫做柔性数组成员 二进制安全&am…

python绘制堆叠柱状图_matplotlib绘图优化-使用np.histogram绘制直方图(柱状图) | 文艺数学君...

摘要这一篇介绍了绘制直方图的方式,我们使用np.histogram与plt.bar的方式完成了与plt.hist同样的效果,同时绘制了多个直方图与堆叠直方图(柱状图). 简介 这里会介绍绘制直方图的一些方式。其实绘制直方图可以使用plt.hist来进行绘制,参考连接…

新年计划

年底了,公司里开始各种总结,计划的。这里顺便也对自己明年的学习生活做个计划1 学习英语,不管是工作还是玩单片机,编程都需要用到英语。今年已经坚持了1个月了,每天背单词。将碰到的不会的单词记录下来背诵&#xff0…

深入理解redis之事务与乐观锁的实现

事务:要么同时成功,要么同时失败。 事务的特性: 一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行。且不会被其他事务所打断。一组事务中的所有操作,要么全…