【Linux】第十六章 高级IO (五种IO模型+fcntl)

news/2024/9/18 15:23:13/ 标签: linux, java, 算法

文章目录

  • 五种 IO 模型
    • 异步IO 和 同步IO
    • 同步通信 和 异步通信
    • 同步通信 和 同步与互斥
    • fcntl-设置非阻塞IO
      • 测试


IO主要分为两步:

  • 第一步是等,即等待IO条件就绪。
  • 第二步是拷贝,也就是当IO条件就绪后将数据拷贝到内存或外设。

让IO变得高效,最核心的办法就是尽量减少“等”的时间

五种 IO 模型

  • A, 拿着鱼竿去钓鱼,一直盯着鱼漂,鱼漂有动静就收钩

  • B, 拿着鱼竿去钓鱼,时不时看看鱼漂,有动静就收购

  • C, 拿着鱼竿去钓鱼,在鱼漂上弄个铃铛,然后干其他的事情,听到铃铛的声音就收钩

  • D, 拿了一大堆鱼竿过来,都摆弄好,只要有一个鱼漂有动静,就收钩

  • E 是大老板,直接叫人帮忙钓鱼,钓到一定数量的🐟后通知自己,自己过来取🐟

    这五种钓鱼方式,就对应了五种 IO 模型

  • A, 阻塞等待 , 等待到数据就立即读取

  • B, 轮询检测 , 检测到数据的时候读取

  • C, 利用铃铛来作为通知方式,听到了信号之后,就去读取数据(信号驱动

  • D, 一次性检测多个文件描述符(多路转接

  • E, 没有自己参与钓鱼过程,有别人帮忙监控文件描述符,自己只关心拿走数据(异步 IO

ABC效率本质上是一样,D 的效率是最高的,ABCD是同步IO

异步IO 和 同步IO

  • 异步IO没有参与IO细节,不需要你进行“等”和“拷贝”的操作
  • 同步IO有参与IO细节

同步通信 和 异步通信

  • 异步通信:在调用发出后,这个调用直接返回,并没有携带结果
  • 同步通信:在发出调用后,没有得到结果前,该调用不返回

同步通信 和 同步与互斥

  • 线程和进程的同步指的是线程和进程之间有相互制约的关系,让进程/线程能够按照某种特定的顺序访问临界资源
  • 而同步IO指的是进程/线程与操作系统之间的关系,谈论的是进程/线程是否需要主动参与IO过程

fcntl-设置非阻塞IO

默认创建的都是阻塞的文件描述符,我们可以使用 fcntl 来将文件描述符设置成非阻塞的

#include <unistd.h>
#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );
  • 复制一个现有的描述符(cmd=F_DUPFD)
  • 获得 / 设置文件描述符标记 (cmd=F_GETFD 或 F_SETFD)
  • 获得 / 设置文件状态标记 (cmd=F_GETFL 或 F_SETFL)
  • 获得 / 设置异步 I/O 所有权 (cmd=F_GETOWN 或 F_SETOWN)
  • 获得 / 设置记录锁 (cmd=F_GETLK, F_SETLK 或 F_SETLKW)
  • … 可变参数,传入的cmd值不同,后面追加的参数也不同。

返回值

  • 如果函数调用成功,则返回值取决于具体进行的操作。
  • 如果函数调用失败,则返回-1,同时错误码会被设置。

测试

定义一个函数,该函数就用于将指定的文件描述符设置为非阻塞状态

bool SetNonBlock(int fd)
{//传入的cmd值为F_SETFL,获取文件已有状态int fl = fcntl(fd, F_GETFL);if (fl < 0){std::cerr << "fcntl error" << std::endl;return false;}//添加非阻塞标记O_NONBLOCKfcntl(fd, F_SETFL, fl | O_NONBLOCK);return true;
}

stdin(0号文件描述符)输入的时候,进程就是处于阻塞状态,等待输入,如果我们改成非阻塞,那么stdin不会阻塞

int main()
{SetNoBlock(stdin->_fileno);char buf[1024];while(true){ssize_t read_size = read(stdin->_fileno, buf, sizeof(buf) - 1);if(read_size < 0){perror("read err");sleep(2);continue;}printf("input:%s\n", buf);buf[0] = '\0';}return 0;
}

没有输入就会一直循环打印报错,如果有输出内容就会把输出内容打印

read err: Resource temporarily unavailable
read err: Resource temporarily unavailable
read err: Resource temporarily unavailable
read err: Resource temporarily unavailable
123
input:123read err: Resource temporarily unavailable


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

相关文章

排序算法(冒泡、插入、选择、快排、归并)原理动画及Python、Java实现

排序算法&#xff08;冒泡、插入、选择、快排、归并&#xff09;原理动画及Python、Java实现 1 冒泡排序1.1 原理1.2 Python、Java实现 2 插入排序2.1 原理2.2 Python、Java实现 3 选择排序3.1 原理3.2 Python、Java实现 4 快速排序4.1 原理4.2 Python、Java实现 5 归并排序5.1…

【十四届蓝桥杯省赛C++试卷】

一、选择题 第一题 C 中&#xff0c; bool 类型的变量占用字节数为&#xff08; &#xff09;。 A 、 1 B 、 2 C 、 3 D 、 4 答案&#xff1a;A 解析&#xff1a;&#xff08;C 中 bool 类型与 char 类型一样&#xff0c;都需要1 byte。一些其他类型的占用字节数&…

streeapptest 工具编译看 + 测试rk3568

首先来了解一下 stressappteset 网上的资料 压力测试不就是 内存的接口测试吗&#xff1f; 网上找了些资料&#xff0c;基本没有这个工具对于 磁盘网络的测试。 我的理解&#xff0c;压力测试应该指的就是 CPU内存的测试吧。 然后是 关于这个 软件的编译。 首先是下载 git c…

JavaScript(28)——正则表达式

定义正则表达式语法&#xff1a; const 变量名 /表达式/ 判断是否有符合规则的字符串&#xff1a; test()方法 用来查看正则表达式与指定的字符串是否匹配 语法&#xff1a; regObj.test(被检测的字符串) //返回布尔值 regObj.exec(字符串) //返回的是数组 <script>…

docker的部署及基本用法

目录​​​​​​​ 1 docker 介绍 1.1 什么是docker&#xff1f; 1.2 docker在企业中的应用场景 1.3 docker与虚拟化的对比 1.4 docker的优势 1.5 容器工作方式 2 部署docker 2.1 配置软件仓库 2.2 docker 安装 2.3 配置docker 镜像加速器 2.4 启动服务 2.5 激活内核网络选项…

每日刷力扣SQL题(五)

1164.指定日期的产品价格 一、方法&#xff1a;使用left join 和 ifnull 思路 本题的关键点在找到 2019-08-16 前所有有改动的产品及其最新价格和没有没有修改过价格的产品。 我们可以先找到所有的产品&#xff0c;再找到所有 2019-08-16 前有修改的产品和他们最新的价…

Vue3 pinia

1.简介 集中式状态&#xff08;数据&#xff09;管理 和vueX一样 2.安装pinia npm i pinia //引入 createApp用于创建应用 import {createApp} from vue; //引入 App 根组件 import App from ./App.vue;//引入pinia import {createPinia} from pinia;//创建一个应用 const…

PyTorch构建模型网络结构的6种方式

PyTorch提供了多种方式来构建模型的网络结构&#xff0c;我尝试总结一下&#xff0c;有如下6种常见方式&#xff08;可能还有我没注意到的&#xff0c;欢迎补充&#xff09;。我们平时写代码并不一定需要掌握全部方式&#xff0c;但是多了解一些&#xff0c;对于阅读理解别人的…

服务器主动推送的方法

目录 1.长轮询&#xff08;Long Polling&#xff09;2.WebSockets3.Server-Sent Events&#xff08;SSE&#xff09;4.HTTP2 Server Push 服务器如何主动推送数据 在传统的网络通信中&#xff0c;客户端&#xff08;如浏览器&#xff09;通常需要通过向服务器发起请求来获取数据…

快速判断一个项目是Spring MVC框架还是Spring Boot框架

1. 查看项目的启动类 Spring Boot: 通常有一个主类&#xff0c;包含 SpringBootApplication 注解&#xff0c;并且有一个 main 方法来启动应用程序。 SpringBootApplication public class Application {public static void main(String[] args) {SpringApplication.run(Appli…

作业训练三编程题13. 导弹防御系统

【问题描述】 某国为了防御敌国的导弹袭击&#xff0c;开发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷&#xff1a;虽然它的第一发炮弹能够到达任意的高度&#xff0c;但是以后每一发炮弹都不能高于前一发的高度。某天&#xff0c;雷达捕捉到敌国的导弹来袭&#xf…

python脚本请求数量达到上限,http请求重试问题例子解析

在使用Python的requests库进行HTTP请求时&#xff0c;可能会遇到请求数量达到上限&#xff0c;导致Max retries exceeded with URL的错误。这通常发生在网络连接不稳定、服务器限制请求次数、或请求参数设置错误的情况下。以下是一些解决该问题的策略&#xff1a; 增加重试次数…

并发服务器开发基础

一、服务器模型 1. 单循环服务器&#xff1a; 单循环服务器在同一时刻只能处理一个客户端的请求。由于其结构简单&#xff0c;适合低负载的场景&#xff0c;但在并发请求增加时可能导致性能问题。 2. 并发服务器模型&#xff1a; 并发服务器可以同时响应多个客户端…

本地环境注入jupyter:无法在jupyter选择已经创建的conda环境?快来看下解决办法(jupyter notebook选择已创建环境)

1、WinR打开本机cmd命令行 2、运行 conda activate 本地已创建的环境名称 3、运行 conda install ipykernel 4、运行 python -m ipykernel install --user --name 本地环境名称 --display-name "在jupyter上显示的环境名称" 就可以在jupyter notebook中看到环…

谷粒商城实战笔记-250-商城业务-消息队列-RabbitMQ安装-Docker

一&#xff0c;docker安装RabbitMq RabbitMQ 是一个开源的消息代理软件&#xff0c;广泛用于实现异步通信和应用程序解耦。 使用 Docker 容器化技术可以简化 RabbitMQ 的安装和部署过程。 以下是使用 Docker 安装 RabbitMQ 的详细步骤。 步骤 1: 安装 Docker 如果您的系统…

如何解决:Failed to start jenkins.service: Unit not found.

当在 CentOS 上尝试启动 Jenkins 服务时&#xff0c;出现 Failed to start jenkins.service: Unit not found 的错误&#xff0c;这通常表示 Jenkins 服务未安装或未正确配置。请按照以下步骤进行排查和解决&#xff1a; 解决步骤 检查 Jenkins 是否已安装&#xff1a; 确认 J…

如何使用ssm实现旅游网站的设计与实现

TOC ssm150旅游网站的设计与实现jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管…

ComfyUI 常用的节点

总的来说&#xff0c;如果可以的话 最佳实践是直接访问每个节点仓库&#xff0c;仔细阅读作者提供的文档和说明。然后&#xff0c;手动执行 git clone 来获取仓库的代码。 接着&#xff0c;你可以通过手动执行 pip install -r requirements.txt 来安装每个项目的依赖。这种方法…

【Linux】第十八章 Reactor模式

文章目录 Reactor模式epoll ET服务器&#xff08;Reactor模式&#xff09;设计思路Epoller.hppSock.hppProtocol.hppService.hppTcpServer.hpp-重点Connection类TcpServer类服务器框架TcpServer构造AddConnection函数SetNonBlock 函数Accepter函数IsExists函数TcpRecver函数Tcp…

[oeasy]python031_[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics

[趣味拓展]unix起源_Ken_Tompson_Ritchie_multics &#x1f94b; 回忆上次内容 上次 动态设置了 断点 断点 可以把代码 切成一段一段的可以 更快地调试 调试的目的 是 去除 bug 别害怕 bug 一步步 总能找到 bug这 就是 程序员基本功 调试 debug 在bug出现的时候 甚至…