如何理解高效IO

目录

前言

1.如何理解高效的IO

2.五种IO模型

3.非阻塞IO

4.非阻塞代码编写

总结 


前言

        哈喽,很高兴和大家见面!今天我们要介绍的关于IO的话题,在计算机中IO是非常常规的操作,例如将数据显示到外设,或者将数据从主机A发送到主机B……为了提高性能,减少IO的时间成为了一个人们比较关心的话题,而今天我们要介绍的是如何做才能提高IO效率。

1.如何理解高效的IO

IO:本质上是将数据从一方拷贝到另一方例如:调用read/recv读数据, 本质是将缓冲区的数据拷贝一份!但是拷贝数据的前提是要有数据,所以IO的过程包含两部分,一部分是等数据准备好,另一部分才是拷贝数据。因为拷贝数据的效率是由硬件本身决定的,所以要做到高效的IO,是要减少等的时间!

2.五种IO模型

举例说明:钓鱼的例子
张三坐在河边一动不动的等着鱼上钩
李四将鱼竿放在河边,然后就去做别的事情,然后隔一段时间看看有没有鱼上钩
五在鱼竿上放一个铃铛,将鱼竿放在河边,然后就去做别的事情,等铃铛响了就说明有鱼上钩了,然后把鱼钓上来
赵六带了一群鱼竿,然后都放在河边,然后就轮询的查看是否有鱼上钩
田七:找了一个人小刘,帮他钓鱼,等鱼钓上来,小刘通知田七,然后让田七把鱼拿走

其中张三对应于阻塞式IO
李四对应非阻塞式IO
王五对应信号驱动式IO
赵六对应多路转接/多路复用IO
田七对应异步IO
其中张三,李四,王五在效率上并没有什么差别!从整齐上来看李四和王五在钓鱼期间可以做其它的事情
信号驱动式IO:虽然是等信号发送了之后才会去拷贝数据,但是本质上也是等了!

四种方式,每个人都等了钓鱼->属于同步IO
第五种方式,没有参与IO阶段中任何阶段->属于异步IO
对于阻塞式IO和非阻塞式IO的差别:
相同点:都会进行数据拷贝
不同点:等的方式不同

阻塞式IO模型:

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

非阻塞式IO模型:

如果内核还未将数据准备好, 系统调用仍然会直接返回, 并且返回EWOULDBLOCK错误码.
非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一般只有特定场景下才使用.

信号驱动式IO模型:

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

IO多路转接模型:

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

异步IO:

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

小结
任何IO过程中, 都包含两个步骤. 第一是等待, 第二是拷贝. 而且在实际的应用场景中, 等待消耗的时间往往都远远高于拷贝的时间. 让IO更高效, 最核心的办法就是让等待的时间尽量少. 

3.非阻塞IO

一个文件描述符, 默认都是阻塞IO.

fcntl()函数原型如下.

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

传入的cmd的值不同, 后面追加的参数也不相同.
fcntl函数有5种功能:
 

复制一个现有的描述符(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).
我们此处只是用第三种功能, 获取/设置文件状态标记, 就可以将一个文件描述符设置为非阻塞

实现函数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.非阻塞代码编写

说明:用户向缓冲区输入数据,然后将数据读出来打印到显示器,显示器本质上也是一个文件,对应的文件描述符为0,此时将0号文件描述符对应的文件设置为非阻塞,当有数据的时候读取数据,没有数据的时候可以处理其它的业务,而不是阻塞式等待。

main.cc

#include"util.hpp"
#include<functional>
#include<vector>
using func_t = std::function<void()>;#define INIT(v) do {\v.push_back(PrintLog);\v.push_back(Download);\
}while(0)
#define callback(cal) do{\for(auto& e: cal) e();\
}while(0);
int main()
{std::vector<func_t> cbs;INIT(cbs);setNoBlock(0);while(true) {char buf[1024];printf(">>> ");fflush(stdout);int ret = read(0,buf,sizeof(buf)-1);if(ret == 0) {std::cout<< "read end" << std::endl;break;}else if(ret > 0){buf[ret-1] = 0;std::cout << "echo# " << buf << std::endl;}else {//不输入的时候,底层没有数据,不算错误,只不过是以错误的形式返回了//如何区分是真的错了还是没有数据//EAGAIN 和 EWOULDBLOCK 都表示没有数据if(errno == EAGAIN || errno == EWOULDBLOCK) {std::cout << "没有数据" << std::endl;callback(cbs);}else if(errno == EINTR) continue;else {//真的错了std::cout << ret << "errno: "<< strerror(errno) << std::endl;break;}}sleep(1);}return 0;
}

util.hpp:

#include<iostream>
#include<cstring>
#include<errno.h>
#include<unistd.h>
#include<fcntl.h>void setNoBlock(int fd) {int f1 = fcntl(fd,F_GETFL);if(f1 < 0) std::cerr<< "fcntl fail: " << strerror(errno) << std::endl; fcntl(fd,F_SETFL,f1 | O_NONBLOCK);
}
void PrintLog() {std::cout << "this is a LOG" << std::endl;
}
void Download() {std::cout << "this is a Download" << std::endl;
}

运行截图:

总结 

        相信看完这篇文章之后,你一定可以理解要想实现高效的IO,必须要减少等的时间,如何减少等的时间呢?关于这个话题,一般采用IO多路转接的方案,IO多路转接包含select模型,poll模型,epoll模型,关于这三种模型,在后续的文章中为大家一一介绍,感谢大家的阅读,今天我们介绍的内容就结束了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode75】第五十九题 第N个泰波那契数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目顾名思义&#xff0c;让我们求出第N个泰波那契数&#xff0c;也就是除了开头三个数之外&#xff0c;第四个数开始就是等于前三个数之…

基于 Alpine 环境构建 aspnetcore6-runtime 的 Docker 镜像

关于 Alpine Linux 此处就不再过多讲述&#xff0c;请自行查看相关文档。 .NET 支持的体系结构 下表列出了当前支持的 .NET 体系结构以及支持它们的 Alpine 版本。 这些版本在 .NET 到达支持终止日期或 Alpine 的体系结构受支持之前仍受支持。请注意&#xff0c;Microsoft 仅正…

Jenkins+Gitee+Docker+Ruoyi项目前后端分离部署

前言 描述&#xff1a;本文主要是用来记录 如何用标题上的技术&#xff0c;部署到云服务器上通过ip正常访问。 一、总览 1.1、Docker做的事 拉取 mysql 镜像拉取 redis 镜像拉取 jdk 镜像拉取 nginx 镜像 解释说明&#xff1a;前端项目的打包文件放在 nginx容器运行。后端…

PWMADC重要参数

频率的计算 1、 ARR&#xff08;TIM_Period&#xff09; 是计数值&#xff1b; 2、 PSC&#xff08;TIM_Prescaler&#xff09; 是预分频值。 频率计算公式&#xff1a;Fpwm 主频 / ((ARR1)*(PSC1))(单位&#xff1a;Hz) 占空比的计算 计算公式&#xff1a;duty circle TIM3…

部署大数据平台详细教程以及遇到的问题解答(ubuntu18.04下安装ambari2.7.3+HDP3.1.0)

节点准备: 我搭建的是3台,节点可以随意。建议最少是3台 hostname ip 角色 ubuntu-1804-1 172.21.73.53 从节点 ubuntu-1804-2 172.21.73.54 主节点 ubuntu-1804-3 172.21.73.55 从节点 一:关闭所有节点的防火墙 sudo ufw disable二:配置时钟同步NTP 所有节点安装ntp sud…

Lua学习笔记:探究package

前言 本篇在讲什么 理解Lua的package 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级…

腾讯云微服务平台 TSF 异地多活单元化能力重磅升级

导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕&#xff0c;40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场&#xff0c;腾讯云微服务平台 TSF 产品经理张桢带来了《腾讯云微服务平台 TSF 异地多活单元化能力重磅升级》的精彩演讲。本…

Unity的配置文件在安卓路径下使用的方法

Unity的配置文件在安卓路径下使用的方法 前言 之前我做过的很多使用配置文件的Unity项目&#xff0c;后面的有些项目也有在安卓路径下读取json文件的需求。这几天有个需求是获取在安卓路径下配置文件里的数据&#xff0c;我在网上查了一些案例&#xff0c;简单实现了这个需求…

内网穿透的应用-Cloudreve搭建云盘系统,并实现随时访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了&#xff0c;各互联网大厂也纷纷加入战局&#…

小样本目标检测:ECEA: Extensible Co-Existing Attention for Few-Shot Object Detection

论文作者&#xff1a;Zhimeng Xin,Tianxu Wu,Shiming Chen,Yixiong Zou,Ling Shao,Xinge You 作者单位&#xff1a;Huazhong University of Science and Technology; UCAS-Terminus AI Lab 论文链接&#xff1a;http://arxiv.org/abs/2309.08196v1 内容简介&#xff1a; 1&…

C++const关键字

本文旨在讲解C中相关const关键字的详解&#xff0c;希望读完本篇文章&#xff0c;可以让诸位对C中的const关键字有更深一步的认识&#xff01; 在C中&#xff0c;若想让类中某一个变量不再改变&#xff0c;可以使用const关键字进行修饰&#xff0c;让数据不被修改&#xff0c;使…

2023-09-19 LeetCode每日一题(打家劫舍 IV)

2023-09-19每日一题 一、题目编号 2560. 打家劫舍 IV二、题目链接 点击跳转到题目位置 三、题目描述 沿街有一排连续的房屋。每间房屋内都藏有一定的现金。现在有一位小偷计划从这些房屋中窃取现金。 由于相邻的房屋装有相互连通的防盗系统&#xff0c;所以小偷 不会窃取…

xp 系统 安装 python 2.7 ide pip

1 下载python http://www.python.org/ftp/python/ python-2.7.2.msi 安装完需要设置环境变量 2 下载 setuptools setuptools-0.6c11.win32-py2.7.exe https://pypi.tuna.tsinghua.edu.cn/simple/setuptools/ 3 下载 pip &#xff0c;python 2.7 最高支持 pip 20.3.4 https:…

Palantir的“英伟达时刻”即将到来

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结 &#xff08;1&#xff09;由于投资者对生成式人工智能的兴趣持续增加&#xff0c;Palantir的股价一直在上涨。 &#xff08;2&#xff09;Palantir已经连续三个季度实现了GAAP盈利&#xff0c;并将很快有资格被纳入标…

027-从零搭建微服务-搜索服务(一)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

理解QT信号和槽

进入QT官网&#xff0c;注册&#xff0c;创建账号&#xff0c;登录&#xff1b; 下载在线安装程序&#xff1b;10天试用版本&#xff1b;安装&#xff1b;完成后如下&#xff1b; 新建一个widgets项目&#xff0c;也就是桌面的窗口应用&#xff1b; 按向导新建完成项目&#x…

【云原生】k8s-----集群调度

目录 1.k8s的list-watch机制 1.1 list-watc机制简介 1.2 根据list-watch机制&#xff0c;pod的创建流程 2.scheduler的调度策略 2.1 scheduler的调度策略简介 2.2 Scheduler预选策略的算法 2.3 Scheduler优选策略的算法 3. k8s中的标签管理及nodeSelector和nodeName的 调…

Hadoop的HDFS高可用方案

一、Hadoop高可用简介 Hadoop 高可用 (High Availability) 分为 HDFS 高可用和 YARN 高可用&#xff0c;两者的实现基本类似&#xff0c;但 HDFSNameNode 对数据存储及其一致性的要求比 YARN ResourceManger 高得多&#xff0c;所以它的实现也更加复杂 1、HDFS系统高可用简介…

八大排序(二)--------冒泡排序

本专栏内容为&#xff1a;八大排序汇总 通过本专栏的深入学习&#xff0c;你可以了解并掌握八大排序以及相关的排序算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;八大排序汇总 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库…

Mac cocoapod 3分钟安装教程( 国内镜像源方法)

参考链接&#xff1a;2023最新总结&#xff0c;Mac下使用Homebrew完全指南&#xff01; - 知乎 1.打开终端&#xff0c; 执行&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 2.运行&#xff0c;可以选择清…