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

liunx io模型多路复用

多路复用

应用程序中同时处理多路输入输出流,若采用阻塞模式,得不到预期的目的;

若采用非阻塞模式,对多个输入进行轮询,但又太浪费CPU时间;

若设置多个进程/线程,分别处理一条数据通路,将新产生进程/线程间的同步与通信问题,使程序变得更加复杂;

 比较好的方法是使用I/O多路复用技术。其(select)基本思想是:

 1.先构造一张有关描述符的表(最大1024),然后调用一个函数。

 2.当这些文件描述符中的一个或多个已准备好进行I/O时函数才返回。

3. 函数返回时告诉进程哪个描述符已就绪,可以进行I/O操作。

select

通过man手册得到函数的用法及参数:

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

功能:

实现IO的多路复用

参数:

nfds:关注的最大的文件描述符+1

readfds:关注的读表

writefds:关注的写表

exceptfds:关注的异常表

timeout:超时的设置

编程步骤:

  1. 构造一张关于文件描述符的表
  2. 清空表 FD_ZERO
  3. 将关心的文件描述符添加到表中 FD_SET
  4. 调用select函数,监听 select
  5. 判断到底是哪一个或者是哪些文件描述符发生了事件 FD_ISSET
  6. 做对应的逻辑处理 

通过代码实现:输入鼠标的时候, 响应鼠标事件, 输入键盘的时候, 响应键盘事件 (两路IO)


#include <stdio.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>int main(int argc, char const *argv[])
{char buf[128] = {0}; // 用于存储读取的数据int fd = open("/dev/input/mouse0", O_RDONLY); // 打开鼠标设备文件if (fd < 0){perror("open err"); // 打开文件出错return -1;}fd_set rfds; // 文件描述符集合while (1){FD_ZERO(&rfds); // 清空文件描述符集合FD_SET(fd, &rfds); // 将鼠标设备的文件描述符加入集合FD_SET(STDIN_FILENO, &rfds); // 将标准输入的文件描述符(键盘)加入集合// 监听文件描述符是否有可读事件int ret = select(fd + 1, &rfds, NULL, NULL, NULL);if (ret < 0){perror("select err"); // select 出错close(fd);return -1;}// 检查标准输入是否有数据可读if (FD_ISSET(STDIN_FILENO, &rfds)){fgets(buf, sizeof(buf), stdin); // 从标准输入读取数据printf("键盘输入: %s\n", buf);}// 检查鼠标设备是否有数据可读if (FD_ISSET(fd, &rfds)){ssize_t n = read(fd, buf, sizeof(buf)); // 从鼠标设备读取数据if (n < 0){perror("read err"); // 读取设备出错}else{printf("鼠标数据: ");for (ssize_t i = 0; i < n; ++i){printf("%02x ", (unsigned char)buf[i]); // 以十六进制打印鼠标数据}printf("\n");}}memset(buf, 0, sizeof(buf)); // 清空缓冲区}close(fd); // 关闭文件描述符return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 2024年【甘肃省安全员C证】报名考试及甘肃省安全员C证考试总结
  • MyBatis详解
  • ios签名怎么找靠谱的服务商
  • 睿考网:中级经济师考试题型有哪些?
  • 小米嵌入式面试题目RTOS面试题目 嵌入式面试题目
  • 【QT Creator】基本使用
  • 2025通信硕士找工作纪实
  • Scratch中秋节——嫦娥奔月
  • 如何从0到1本地搭建whisper语音识别模型
  • OpenHarmony鸿蒙开发( Beta5.0)无感配网详解
  • 「大数据分析」Pandas图形可视化,基本绘图:折线图及实践
  • SpringBoot教程(二十八) | SpringBoot集成Elasticsearch(Java High Level Rest Client方式)
  • Prometheus+Grafana普罗米修斯,搭建和使用
  • [最优化方法] 《最优化方法》个人问答式学习笔记 with LLM
  • Java语言程序设计基础篇_编程练习题*18.9 (以逆序输出一个字符串中的字符)
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • Angular6错误 Service: No provider for Renderer2
  • javascript面向对象之创建对象
  • markdown编辑器简评
  • supervisor 永不挂掉的进程 安装以及使用
  • uva 10370 Above Average
  • web标准化(下)
  • 对象引论
  • 前嗅ForeSpider教程:创建模板
  • 区块链共识机制优缺点对比都是什么
  • 使用docker-compose进行多节点部署
  • 听说你叫Java(二)–Servlet请求
  • 用jQuery怎么做到前后端分离
  • 用Python写一份独特的元宵节祝福
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 追踪解析 FutureTask 源码
  • 白色的风信子
  • ​2020 年大前端技术趋势解读
  • ​TypeScript都不会用,也敢说会前端?
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • ######## golang各章节终篇索引 ########
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #前后端分离# 头条发布系统
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (2)MFC+openGL单文档框架glFrame
  • (二)hibernate配置管理
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (七)Flink Watermark
  • (五十)第 7 章 图(有向图的十字链表存储)
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)http协议
  • (转)程序员技术练级攻略
  • (转载)虚函数剖析