当前位置: 首页 > news >正文

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


文章目录

  • 五种 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.mrgr.cn/news/9846.html

相关文章:

  • 什么是ElasticSearch的深度分页问题?如何解决?
  • NRK3301语音识别芯片在汽车内饰氛围灯上的应用方案解析
  • Vue3 获取农历(阴历)日期,并封装日历展示组件
  • 泰国中小企业局局长率考察团到访深兰科技
  • SpringBoot天猫商城基于前后端分离+SpringBoot+BootStrap、Vue.js、JQuery+JPA+Redis
  • Node.js 安装教程
  • C语言:动态内存管理
  • 【数学建模】层次分析法
  • 神经网络算法 - 一文搞懂回归和分类
  • 献给正在挣扎中的技术人!
  • C语言:科目二【基础知识】
  • MATLAB 沿任意方向分层点云(82)
  • 【STM32】电容触摸按键
  • DevOps实现CI/CD实战(二)-Jenkins配置
  • 大厂面试官问我:为什么 Object 有 wait ,为什么不全在 Thread 类上写?【后端八股文十六:Java基础合集】
  • 【Rust光年纪】文本分析利器:探索Rust语言的多功能文本处理库
  • C学习(数据结构)-->二叉树
  • 【学习笔记】灰色预测 GM(1,1) 模型 —— Matlab
  • springboot3 SecurityConfig SecurityFilterChain 需要使用CorsFilter,实际是CorsWebFilter
  • c++的delete声明可以用在不是类的内置函数里面