【在Linux世界中追寻伟大的One Piece】五种IO模型和阻塞IO
目录
1 -> 五种IO模型
1.1 -> 阻塞IO(Blocking IO)
1.2 -> 非阻塞IO(Non-blocking IO)
1.3 -> 信号驱动IO(Signal-Driven IO)
1.4 -> IO多路转接(IO Multiplexing)
1.5 -> 异步IO(Asynchronous IO)
2 -> 高级IO概念
2.1 -> 同步通信VS异步通信(synchronous communication/asynchronous communication)
2.2 -> 阻塞VS非阻塞
2.3 -> 非阻塞IO
2.3.1 -> fcntl函数
3 -> 实现函数SetNoBlock
4 -> 轮询方式读取标准输入
1 -> 五种IO模型
1.1 -> 阻塞IO(Blocking IO)
阻塞IO是一种同步IO模型,它是最基本的IO模型。在这种模型中,当一个线程调用read()或write()进行IO操作时,该线程被阻塞,即线程会暂停执行直到有数据被读取或数据完全写入。在此期间,线程不能执行其他操作。阻塞IO的特点是实现简单,但在高并发场景下,每个线程都可能长时间处于阻塞状态,导致系统资源利用率低下。
在阻塞IO模型中,如果应用程序尝试读取数据,而内核的缓冲区中没有数据可读,那么应用程序会阻塞等待,直到数据准备好。同样,如果应用程序尝试写入数据,但内核的缓冲区已满,写入操作也会阻塞,直到有空间可用。
阻塞IO通常用于连接数较少且每个连接都有大量数据交换的应用场景。在这种情况下,每个连接都可以由一个单独的线程处理,从而简化编程模型。
总的来说,阻塞IO是在内核将数据准备好之前,系统调用会一直等待。所有的套接字,默认都是阻塞方式。
阻塞IO是最常见的IO模型。
1.2 -> 非阻塞IO(Non-blocking IO)
非阻塞IO允许线程发起IO请求后立即返回,即使数据还没有准备好。在这种模式下,线程可以进行其他任务,而不是等待IO操作完成。如果数据准备好,线程可以继续执行IO操作;如果没有,线程可以轮询或执行其他任务。非阻塞IO适用于需要处理大量并发连接但每个连接的数据量不大的场景。
总的来说,如果内核还未将数据准备好,系统调用仍然会直接返回,并且返回EWOULDBLOCK错误码。非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符,这种过程称为轮询。这对CPU来说是较大的浪费,一般只有特定场景下才使用。
1.3 -> 信号驱动IO(Signal-Driven IO)
信号驱动IO(Signal-Driven IO)是一种IO模型,它允许应用程序在数据准备好时通过信号来处理IO事件。在这种模型中,当用户线程发起一个IO请求操作时,会给对应的socket注册一个信号函数,然后用户线程会继续执行。当内核数据就绪时,会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用IO读写操作来进行实际的IO请求操作。
信号驱动IO特别适合于UDP套接字,因为在UDP中,SIGIO信号会在数据报到达套接字或套接字上发生错误时产生。这样,应用程序可以在信号处理函数中读取数据,而不需要不断轮询。
在TCP套接字中,SIGIO信号的使用并不常见,因为TCP是双工的,信号产生得过于频繁,并且信号的出现并没有告诉我们发生了什么事情。因此,对于TCP套接字,SIGIO信号的使用是有限的。
总的来说,信号驱动IO是内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作。
1.4 -> IO多路转接(IO Multiplexing)
IO多路转接是一种网络编程技术,它允许一个或多个进程使用单个或少量的线程高效地管理多个网络连接。这种技术通过内核提供的系统调用来实现,内核会监视多个文件描述符,当这些文件描述符上的IO事件(如可读、可写)准备就绪时,内核会通知应用程序。这样,应用程序就可以在同一个线程中同时处理多个网络连接,而不是为每个连接创建一个新的线程,从而提高了程序的并发处理能力和系统资源的利用率。
在Linux系统中,常见的IO多路转接技术包括select、poll和epoll。这些技术在处理大量并发连接时非常有用,尤其是在构建高性能的服务器应用程序时。
虽然从流程图上看起来和阻塞IO类似。实际上最核心在于IO多路转接能够同时等待多个文件描述符的就绪状态。
1.5 -> 异步IO(Asynchronous IO)
异步IO(Asynchronous IO)是一种IO处理模式,它允许应用程序在发起一个IO操作后立即继续执行其他任务,而不需要等待IO操作的完成。在异步IO模型中,当应用程序发起一个IO请求时,它会立即返回,应用程序可以继续处理其他任务。一旦IO操作完成,系统会通过某种机制通知应用程序,应用程序可以在适当的时候处理IO操作的结果。这种模型可以显著提高程序的并发处理能力和系统资源的利用率,尤其是在处理大量并发IO请求时。
总的来说,异步IO是由内核在数据拷贝完成时,通知应用程序(而信号驱动是告诉应用程序何时可以开始拷贝数据)。
任何IO过程中,都包含两个步骤。第一是等待,第二是拷贝。而且在实际的应用场景中,等待消耗的时间往往都远远高于拷贝的时间。让IO更高效,最核心的办法就是让等待的时间尽量少。
2 -> 高级IO概念
高级IO涉及到文件的IO操作,它包括多种技术,如非阻塞IO、记录锁、IO多路转接、异步IO和存储映射等。这些技术通常依赖于文件描述符(fd)和fcntl函数的支持,用于提高文件IO操作的效率和灵活性。
2.1 -> 同步通信VS异步通信(synchronous communication/asynchronous communication)
同步和异步关注的是消息通信机制。
- 所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回. 但是一旦调用返回,就得到返回值了;换句话说,就是由调用者主动等待这个调用的结果。
- 异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果;换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果;而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。
这里的同步通信和进程之间的同步是完全不相干的概念。
- 进程/线程同步也是进程/线程之间直接的制约关系。
- 是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。尤其是在访问临界资源的时候。
2.2 -> 阻塞VS非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息、返回值)时的状态。
- 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
- 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
2.3 -> 非阻塞IO
2.3.1 -> fcntl函数
fcntl(file control)是一个在UNIX和类UNIX操作系统中用于文件描述符控制的系统调用。它提供了多种功能,包括复制文件描述符、设置文件状态标志、管理文件锁定以及设置文件描述符的异步I/O通知等。fcntl函数的原型通常如下:
#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
其中,fd是要操作的文件描述符,cmd是一个指示要执行的操作的命令,arg是一个可选参数,具体取决于cmd的值。fcntl函数可以接受不同的命令来执行不同的操作,例如:
- F_DUPFD:复制文件描述符。
- F_GETFD 和 F_SETFD:获取和解析文件描述符的标志。
- F_GETFL 和 F_SETFL:获取和解析文件状态标志,如O_NONBLOCK(非阻塞模式)。
- F_GETLK、F_SETLK 和 F_SETLKW:获取、设置和尝试设置记录锁。
- F_GETOWN 和 F_SETOWN:获取和解析接收SIGIO信号的进程ID或进程组ID。
fcntl函数在文件IO操作中非常有用,尤其是在需要对文件描述符进行精细控制时,如设置文件为非阻塞模式或管理多进程对同一文件的并发访问。在网络编程中,fcntl也常用于设置文件描述符的异步通知,允许进程在IO事件发生时接收信号,而不是轮询检查。
3 -> 实现函数SetNoBlock
基于fcntl,我们实现一个SetNoBlock函数,将文件描述符设置为非阻塞。
void SetNoBlock(int fd)
{int fl = fcntl(fd, F_GETFL);if (fl < 0) {perror("fcntl");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}
- 使用F_GETFL将当前的文件描述符的属性取出来(这是一个位图)。
- 然后再使用F_SETFL将文件描述符设置回去。设置回去的同时,加上一个O_NONBLOCK参数。
4 -> 轮询方式读取标准输入
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>void SetNoBlock(int fd)
{int fl = fcntl(fd, F_GETFL);if (fl < 0) {perror("fcntl");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);
}int main()
{SetNoBlock(0);while (1) {char buf[1024] = { 0 };ssize_t read_size = read(0, buf, sizeof(buf) - 1);if (read_size < 0) {perror("read");sleep(1);continue;}printf("input:%s\n", buf);}return 0;
}
感谢各位大佬支持!!!
互三啦!!!
相关文章:

【在Linux世界中追寻伟大的One Piece】五种IO模型和阻塞IO
目录 1 -> 五种IO模型 1.1 -> 阻塞IO(Blocking IO) 1.2 -> 非阻塞IO(Non-blocking IO) 1.3 -> 信号驱动IO(Signal-Driven IO) 1.4 -> IO多路转接(IO Multiplexing) 1.5 -> 异步IO(Asynchronous IO) 2 -> 高级IO概念 2.1 -> 同步通信VS异步通信…...

nginx实现权重机制(nginx基础配置二)
在上一篇文章中我们已经完成了对轮询机制的测试,详情请看轮询机制。 接下来我们进行权重机制的测试 一、conf配置 upstream backServer{ server 127.0.0.1:8080 weight2; server 127.0.0.1:8081 weight1; } server { listen 80; server_name upstream.boyatop.cn…...

华为的仓颉和ArkTS这两门语言有什么区别
先贴下官网: ArkTs官网 仓颉官网 ArkTS的官网介绍说,ArkTS是TypeScript的进一步强化版本,简单来说就是包含了TS的风格,但是做了一些改进。 了解TypeScript的朋友都应该知道,其实TypeScript就是JavaScript的改进版本&…...

(SERIES10)DM逻辑备份还原
1 概念 逻辑备份还原是对数据库逻辑组件(如表、视图和存储过程等数据库对象)的备份还原。逻辑导出(dexp)和逻辑导入(dimp)是 DM 数据库的两个命令行工具,分别用来实现对 DM 数据库的逻辑备份和逻…...

Java零基础-StringBuilder类详解
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互…...

免费爬虫软件“HyperlinkCollector超链采集器v0.1”
HyperlinkCollector超链采集器单机版v0.1 软件采用python的pyside2和selenium开发,暂时只支持window环境,抓取方式支持普通程序抓取和selenium模拟浏览器抓取。软件遵守robots协议。 首先下载后解压缩,然后运行app目录下的HyperlinkCollector.exe 运行…...

OPENAIGC开发者大赛企业组AI黑马奖 | AIGC数智传媒解决方案
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给您…...

k8s(kubernetes)的PV / PVC / StorageClass(理论+实践)
NFS总是不支持PVC扩容 先来个一句话总结:PV、PVC是K8S用来做存储管理的资源对象,它们让存储资源的使用变得可控,从而保障系统的稳定性、可靠性。StorageClass则是为了减少人工的工作量而去自动化创建PV的组件。所有Pod使用存储只有一个原则&…...

前端Excel热成像数据展示及插值算法
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏:《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️生活的理想,就是为了理想的生活! 目录 📘 前言 📘一、热成像数…...

VBA_NZ系列工具NZ01: VBA二维码应用技术
我的教程一共九套及VBA汉英手册一部,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到数据库,到字典,到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑,这么多知识点该如何组织…...

小明震惊OpenAI 的新模型 01
在硅谷的中心,繁忙的咖啡馆和创业中心周围,年轻的软件工程师小明坐在他的办公桌前,面露困惑。科技界一直在盛传一项新的AI突破,但他持怀疑态度,不敢抱太大希望。他认为AI泡沫即将破灭,炒作列车即将出轨&…...

Clickhouse使用笔记
clickhouse官方文档:https://clickhouse.com/docs/zh/sql-reference/data-types/decimal 一,建表 create table acitivity_user_record ( id String DEFAULT generateUUIDv4(), -- 主键自增 activityId String, userId String, userName Nullable(Strin…...

基于高通主板的ARM架构服务器
一、ARM架构服务器的崛起 (一)市场需求推动 消费市场寒冬,全球消费电子需求下行,服务器成半导体核心动力之一。Arm 加速布局服务器领域,如 9 月推出 Neoverse V2。长久以来,x86 架构主导服务器市场&#…...

AV1 Bitstream Decoding Process Specification--[2]:符号和缩写术语
原文地址:https://aomediacodec.github.io/av1-spec/av1-spec.pdf没有梯子的下载地址:AV1 Bitstream & Decoding Process Specification摘要:这份文档定义了开放媒体联盟(Alliance for Open Media)AV1视频编解码器…...

【Python爬虫系列】_022.异步文件操作aiofiles
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈...

GD32E230 RTC报警中断功能使用
GD32E230 RTC报警中断使用 GD32E230 RTC时钟源有3个,一个是内部RC振动器产生的40KHz作为时钟源,或者是有外部32768Hz晶振.,或者外部高速时钟晶振分频作为时钟源。 🔖个人认为最难理解难点的就是有关RTC时钟异步预分频和同步预分频的计算。在对…...

C/C++语言基础--从C到C++的不同(上)
本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 之前更新的C语言,感谢大家的点赞收藏关注,接下来我们逐步也开始更新C;C语言后面也会继续更新知识点,如内联汇编;本人现在正在写一个C语言的图书管理系…...

自动驾驶自动泊车场景应用总结
自动泊车技术是当前智能驾驶技术的一个重要分支,其目标是通过车辆自身的感知、决策和控制系统,实现车辆在有限空间内的自主泊车操作。目前自动泊车可分为半自动泊车、全自动泊车、记忆泊车、自主代客泊车四种产品形态,其中, 根据搭载传感器和使用场景的不同,全自动泊车又可…...

redis常见的数据类型?
参考:一文读懂Redis五种数据类型及应用场景 - 知乎 (zhihu.com) String 类型 String 类型:Redis 最基本的数据类型,它是二进制安全的,意味着你可以用它来存储任何类型的数据,如图片、序列化对象等。使用场景ÿ…...

TCP Analysis Flags 之 TCP ZeroWindow
前言 默认情况下,Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态,并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时,会对每个 TCP 数据包进行一次分析,数据包按照它们在数据包列表中出现的顺序进行处理。可…...

[产品管理-16]:NPDP新产品开发 - 14 - 产品创新流程 - 产品创新流程模型比较:门径、IPD、精益生产、敏捷、系统工程、设计思维、精益创业
目录 一、精益开发与敏捷开发的比较 1、核心理念 2、实践方式 3、应用场景 4、总结 二、门径流程 VS 敏捷方法 1、定义与特点 门径管理流程 敏捷方法 2、应用场景 3、比较 4、总结 三、集成产品开发 VS 系统工程 VS 设计思维 1、集成产品开发(IPD&…...

postgresql 导出CSV格式数据
方法一 psql -c 导出 导出的文件存放在执行psql的客户端。 psql -h 127.0.0.1 -p 5432 -U postgres postgres -Atqc "select oid,relname,relnamespace from tmp_t0 " --csv -o /tmp/test.csv方法二 psql -f 导出 导出的文件存放在执行psql的客户端。 如果查询很长…...

【C++】STL--string(上)
前言 C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留…...

【C++】Stack
个人主页~ Stack 一、Stack的介绍和使用1、stack的介绍2、stack的使用3、stack的模拟实现 二、容器适配器1、什么是适配器2、容器适配器的使用 三、deque1、原理介绍2、deque的使用3、deque的缺陷 一、Stack的介绍和使用 1、stack的介绍 stack详细解释 stack是一种容器适配器…...

“药乡”怀化,按下产业向海“加速键”
怀化,这座被火车拖来的城市,拥有什么独特的产业优势吗? 很多人不知道的是,怀化在整个医药领域可是大名鼎鼎的“中国道地药材之乡”,中药材资源蕴藏量居湖南省第一。尤其是怀化靖州,这里年集散茯苓11万吨&a…...

【AWDP】 AWDP 赛制详解应对方法赛题实践 量大管饱
文章首发于【先知社区】:https://xz.aliyun.com/t/15535 一、AWDP概述 AWDP是什么 AWDP是一种综合考核参赛团队攻击、防御技术能力、即时策略的攻防兼备比赛模式。每个参赛队互为攻击方和防守方,充分体现比赛的实战性、实时性和对抗性,对参…...

读构建可扩展分布式系统:方法与实践05分布式缓存
1. 分布式缓存 1.1. 缓存存在于应用程序的许多地方 1.1.1. 行应用程序的CPU具有高速多级硬件缓存,可以减少相对较慢的主内存访问 1.1.2. 数据库引擎可以利用主内存来缓存数据存储的内容,这样在许多情况下查询就可以不用访问速度相对较慢的磁盘 1.2. …...

【逐行注释】自适应Q和R的AUKF(自适应无迹卡尔曼滤波),附下载链接
文章目录 自适应Q的KF逐行注释的说明运行结果部分代码各模块解释 自适应Q的KF 自适应无迹卡尔曼滤波(Adaptive Unscented Kalman Filter,AUKF)是一种用于状态估计的滤波算法。它是基于无迹卡尔曼滤波(Unscented Kalman Filter&am…...

OpenCV高阶操作
在图像处理与计算机视觉领域,OpenCV(Open Source Computer Vision Library)无疑是最为强大且广泛使用的工具之一。从基础的图像读取、 1.图片的上下,采样 下采样(Downsampling) 下采样通常用于减小图像的…...

Vue中的防抖和节流是什么,它们的作用是什么?
在Vue.js中,防抖(debounce)和节流(throttle)是两种常用的性能优化技术,主要用于处理高频事件,如窗口滚动、窗口大小调整、键盘输入等。 **防抖(Debounce)**:…...