前言

那么这里博主先安利一些干货满满的专栏了!

首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。

高质量干货博客汇总https://blog.csdn.net/yu_cblog/category_12379430.html?spm=1001.2014.3001.5482


1 什么是IO,IO的本质是什么?

要搞清楚这个问题,我们首先要了解5种最重要的IO模型!

  • 阻塞IO

  • 非阻塞IO

  • 信号驱动IO

  • 多路转接

  • 异步IO

1.1 五种IO模型和一些基本概念

1.1.1 阻塞IO

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

简单来说,我要向一个文件描述符做读取这个操作,这个文件描述符里面没有数据,我就一直阻塞等待!

1.1.2 非阻塞IO

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

简单来说,我向一个文件描述符做读取,如果有数据,则成功读取返回,如果没有数据,也返回,但带上EWOULDBLOCK错误码。

使用这种方式的话,我们做读取,就必须每隔一段时间去看看,这个文件描述符到底来数据没有,这个其实就是我们常说的非阻塞轮询检测方案!

轮询一般比较吃CPU资源,因此纯非阻塞IO一般只在特定的场景下使用。

1.1.3 信号驱动IO

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

1.1.4 多路转接

多路转接I/O(Multiplexing I/O)是一种用于管理多个I/O操作的技术。它允许单个线程或进程同时监视和处理多个I/O事件,而无需为每个I/O操作创建单独的线程或进程。

而多路转接I/O利用了操作系统提供的一些机制,如select、poll、epoll(Linux)或kqueue(FreeBSD、Mac OS X),来同时监视多个I/O事件的状态。

这些机制允许程序将多个I/O事件(如套接字的读写事件)注册到一个事件集合中。然后,程序可以通过调用特定的系统调用,如select或epoll_wait,来阻塞等待其中任何一个I/O事件就绪。

一旦有就绪的I/O事件发生,程序就可以通过事件集合得知是哪些I/O操作已经就绪,并对它们进行处理。这种方式避免了阻塞等待单个I/O操作完成的情况,提高了并发处理能力和效率。

多路转接I/O适用于需要同时处理多个I/O事件的情况,特别适用于网络服务器、消息队列、实时流处理等场景。通过使用多路转接I/O,可以减少线程或进程的创建和切换开销,提高系统的性能和资源利用率。

其实通俗来说,就是一个进程,我可以同时监听多个文件描述符,哪一个文件描述符的特定事件就绪了,就提醒上层。

1.1.5 异步IO

异步I/O的关键概念是回调(Callback)和事件循环(Event Loop)。在异步I/O模型中,当程序发起一个I/O操作时,它会注册一个回调函数,并将控制权返回给调用者。当I/O操作完成时,系统会通知程序,并在适当的时机调用事先注册的回调函数。程序可以在回调函数中处理已完成的I/O操作的结果。

异步I/O的优势在于可以在等待I/O操作完成的同时继续执行其他任务,提高了并发处理能力和系统的响应性能。由于无需为每个I/O操作创建额外的线程或进程,异步I/O模型对系统资源的消耗也较低。

比如说Reactor就是一种异步IO的应用,关于Reactor的内容,博主会在后面的内容中进行讲解。

1.1.6 同步通信 vs 异步通信

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

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

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

这个和多线程的同步互斥,不是同一个概念,不要大家不要搞混了。

1.1.7 阻塞队列

阻塞队列其实就是一种同步阻塞IO的应用方式。

多线程|基于阻塞队列和环形队列的生产者消费者模型架构https://blog.csdn.net/Yu_Cblog/article/details/130422047?spm=1001.2014.3001.5502

当然,和这个类似还有环形队列,当然其实本质都一样,因为他们都会阻塞!!

1.2 什么是低效的IO?什么是高效的IO?

我们通过上面的描述,已经可以总结出一个非常非常非常重要的结论:

IO = 等 + 拷贝数据(把数据从文件描述符里拷贝出来或拷贝到文件描述符里去)

这个结论非常的重要!

那么通过这个结论,我们如何提高IO的效率呢?或者说,什么是高效的IO?什么低效呢?

答案:让等的比重降低!!!!!

如何让等的比重降低?最有效的方法其实就是多路转接了。

2 多路转接

其中,值得我们学习的,就是多路转接的select,poll和epoll。

关于这三种多路转接的方式,博主已经做成Github的项目了,大家可以转接上去下载代码和查看相关的原理和区别。

Multiplexing-high-performance-IO-serverhttps://github.com/Yufccode/Multiplexing-high-performance-IO-server

利用多路转接,我们就可以大大提高IO的效率了。

3 为什么需要这些IO模型?

但是上面提到的IO模型,怎么把他们用起来呢?我们为什么要追求极致的效率?为什么我们需要我们的IO很快?

这里会有同学问,我平时在自己电脑上做管道的测试,做文件描述符之间的信息传输,都很快啊,都瞬间传输完成啊,也没有怎么“等”啊,为什么要搞上面这些复杂的IO模型?

其实,本地上,我们肯定看不到IO模型的优势,但是在网络场景下,高效的IO模型就非常重要了!

网络是会丢包的!是会延时的!是会出错的!不然为什么会有TCP这些协议呢?

针对于上面这些IO模型,其实就会衍生出两种主要的网络服务模型,Apache和Nginx。具体内容可以看博主的下一篇博客!

什么是IO?IO的本质?|如何让IO变得高效?何为高效?|异步IO|多路转接|reactor模式的更多相关文章

  1. 同步异步阻塞非阻塞Reactor模式和Proactor模式 (目前JAVA的NIO就属于同步非阻塞IO)

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

  2. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  3. python 自动化之路 day 10 协程、异步IO、队列、缓存

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目 ...

  4. Python全栈开发-Day10-进程/协程/异步IO/IO多路复用

    本节内容 多进程multiprocessing 进程间的通讯 协程 论事件驱动与异步IO Select\Poll\Epoll——IO多路复用   1.多进程multiprocessing Python ...

  5. python之爬虫_并发(串行、多线程、多进程、异步IO)

    并发 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢 import requests def fetch_async(url): res ...

  6. [译]Python中的异步IO:一个完整的演练

    原文:Async IO in Python: A Complete Walkthrough 原文作者: Brad Solomon 原文发布时间:2019年1月16日 翻译:Tacey Wong 翻译时 ...

  7. 【Python之路】异步IO

    线程:CPU基本执行单元,可以与同属一个进程的其他线程共享资源,线程是属于进程的. 进程:资源单元,进程一般由程序.数据集.进程控制块三部分组成.一个进程默认有一个主线程, GIL:用于在进程中对所有 ...

  8. SQLite剖析之异步IO模式、共享缓存模式和解锁通知

    1.异步I/O模式    通常,当SQLite写一个数据库文件时,会等待,直到写操作完成,然后控制返回到调用程序.相比于CPU操作,写文件系统是非常耗时的,这是一个性能瓶颈.异步I/O后端是SQLit ...

  9. 并发式IO的解决方案:多路非阻塞式IO、多路复用、异步IO

    在Linux应用编程中的并发式IO的三种解决方案是: (1) 多路非阻塞式IO (2) 多路复用 (3) 异步IO 以下代码将以操作鼠标和键盘为实例来演示. 1. 多路非阻塞式IO 多路非阻塞式IO访 ...

  10. node源码详解(七) —— 文件异步io、线程池【互斥锁、条件变量、管道、事件对象】

    本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/nodesource7 本博客同步在https://cnodejs.o ...

随机推荐

  1. 0x69 图论-二分图的覆盖与独立集

    A:Machine Schedule 输入 5 5 10 0 1 1 1 1 2 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 3 9 4 3 0 输出 3 在二分图 ...

  2. 0x05 基本算法-排序

    A题:Cinema 经典离散化例题,把电影的语言与字幕和观众懂的语言放进一个数组,然后离散化. 最后统计快乐人数. const int N = 200006; int n, m, a[N], x[N] ...

  3. 如何设置IDEA代码风格为Google风格,使用Google风格format

    1.在Github仓库寻找:google style 为了节省大家时间直接放链接了:Here 2.进到项目 找到名为intellij-java-google-style.xml 文件 Ctrl + F ...

  4. 面试通过,拿到offer了,不去了会怎么样?

    接受了offer但不去,其实没啥事,但这属于诚信问题. 这里有个概念,给了offer但不接受,这没事. 给了offer,也接受了,但在入职前一周(或在其它约定的时间范围内)说不去,同时姿态放低些打招呼 ...

  5. 如何在iOS手机上查看应用日志

    ​ 引言 在开发iOS应用过程中,查看应用日志是非常重要的一项工作.通过查看日志,我们可以了解应用程序运行时的状态和错误信息,帮助我们进行调试和排查问题.本文将介绍两种方法来查看iOS手机上的应用日志 ...

  6. 深入理解 Serverless 计算的并发度

    作者|西流(阿里云技术专家) 背景 2019 年 Berkeley 预测 Serverless 将取代 Serverful 计算[1],成为云计算的计算新范式.Serverless 为应用程序开发提供 ...

  7. S3C2440移植linux3.4.2内核之支持YAFFS文件系统

    上一节S3C2440移植linux3.4.2内核之修改分区以及制作根文件系统我们构建了根文件系统,这节我们修改内核支持yaffs2文件系统 目录 获取yaffs2源码并给内核打补丁 编译内核make ...

  8. 《IT项目管理知识》出书了,特点:全是干货

    大纲目录,及内容如下.本书属于付费内容

  9. Liunx运维(二)-文件与目录操作

    文档目录: 一.pwd:显示当前位置 二.cd:切换目录 三.tree:树形结构显示目录 四.mkdir 创建目录 五.touch:创建空文件或改变文件时间戳 六.ls:显示目录下内容相关属性信息 七 ...

  10. java基础-数组-day06

    1. 引入数组 录入10个学生的成绩 求和 求平均 import java.util.Scanner; public class TestArray01{ public static void mai ...