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

I/O复用

        I/O复用使得程序能够同时监听多个文件描述符,这对提高程序的性能至关重要。

举个例子:

        就好比你天天玩手机,你妈为了监控你,在你房间安装了一个监控,这个监控可以实时监控你的一举一动,并上传到你妈手机上,并提醒你妈,你在玩手机,快去揍他。你看着可不可怕,一看见你玩手机就揍你,没天理。

        I/O复用就是这样 你妈把想监控的事件告诉监控,监控负责监控并通知你妈去 揍你(揍你就是对就绪事件做出的处理)。虽然这个例子不太好,但很形象。

系统函数调用

select系统调用

       #include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

参数: 

  •  nfds:参数类型为int,指被监听的所有文件描述符总数 。它通常被设置为select监听的所有文件描述符中的最大值+1,因为文件描述符是从0开始计数的。
  • readfds,writefds,exceptfds:分别指向 可读,可写和异常等事件对应的文件描述符集合。通过这三个参数传入自己想要监控的文件描述符。select调用返回后,内核将修改他们来通知应用程序那些文件描述符已经就绪。
  • timeout :timeout用来设置select函数的超时调用时间。

返回值

成功返回就绪(可读可写异常)文件描述符总数,在规定时间内没有就绪,就返回0:调用失败返回-1并设置errno;如果在等待时间内接收到信号,则立即返回-1,并设置errno为EINTR。 


fd_set结构体类型 

        fd_set结构体仅包含一个整型数组,该数组中的每一个元素的每一个比特位标记一个文件描述符。里面通过一个宏(FD_SETSIZE),来限制select能同时处理文件的总量

timeout结构体类型

         采用timeval结构体指针,是因为内核将修改它以告诉应用程序select等待了多久,但是select调用失败后,返回的这个值是不确定的

下面就是select系统调用的简单使用

       #include <stdio.h>#include <stdlib.h>#include <sys/select.h>int main(void){fd_set rfds;struct timeval tv;int retval;//下面是监控输入文件描述符 fd = 0/* Watch stdin (fd 0) to see when it has input. */FD_ZERO(&rfds);//将rfds类型的变量的所有比特位置为0FD_SET(0, &rfds);//设置rfds上面的比特位/* Wait up to five seconds. *///设置超时时间tv.tv_sec = 5;tv.tv_usec = 0;retval = select(1, &rfds, NULL, NULL, &tv);//监控的文件描述符是0 填入是就是1/* Don't rely on the value of tv now! */if (retval == -1)perror("select()");else if (retval)//成功返回就绪文件描述符的总数printf("Data is available now.\n");/* FD_ISSET(0, &rfds) will be true. */elseprintf("No data within five seconds.\n");exit(EXIT_SUCCESS);}

上面代码是监控输入文件描述符,在五秒时间内,如果没有输入,就会返回0:有数据就会返回1,因为只监控了一个文件描述符,所以返回1。 

         你也可以进行循环监控。

poll系统调用

       #include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);

参数:

fds:fds参数就是一个pollfd结构体类型数组,后面会讲。

nfds:指定被监听事件集合大小(typedef unsigned long int nfds_t)就是长整型

timeout:参数类型为int,单位为毫秒,指定poll的超时时间。当为-1时,poll将永远阻塞(相当于卡住了,没就绪就不返回),直到发生某个事件;为0时,poll将立即返回(非阻塞(大白话:就是管你就不就绪,立刻返回))

返回值:

成功返回就绪(可读可写异常)文件描述符总数,在规定时间内没有就绪,就返回0:调用失败返回-1并设置errno;如果在等待时间内接收到信号,则立即返回-1,并设置errno为EINTR。


struct pollfd 结构体

  • fd:你要监听的文件描述符
  • events:告诉poll你要监听fd上的那些事件
  • revent:由内核修改,通知应用程序fd上实际发生了那些事件。 

poll事件监控类型

poll简单示例代码 

       #include <poll.h>#include <fcntl.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \} while (0)int main(int argc, char *argv[]){int nfds, num_open_fds;struct pollfd *pfds;if (argc < 2) {fprintf(stderr, "Usage: %s file...\n", argv[0]);exit(EXIT_FAILURE);}num_open_fds = nfds = argc - 1;pfds = (struct pollfd*)malloc(nfds*sizeof(struct pollfd));if (pfds == NULL)errExit("malloc");/* Open each file on command line, and add it 'pfds' array */for (int j = 0; j < nfds; j++) {pfds[j].fd = open(argv[j + 1], O_RDONLY);if (pfds[j].fd == -1){printf("111");errExit("open");}printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);pfds[j].events = POLLIN;//注册可读事件}/* Keep calling poll() as long as at least one file descriptor isopen */while (num_open_fds > 0) {int ready;printf("About to poll()\n");ready = poll(pfds, nfds, -1);//ready = poll(pfds, nfds, -1);if (ready == -1)errExit("poll");printf("Ready: %d\n", ready);/* Deal with array returned by poll() */for (int j = 0; j < nfds; j++) {char buf[10];if (pfds[j].revents != 0) {printf("  fd=%d; events: %s%s%s\n", pfds[j].fd,(pfds[j].revents & POLLIN)  ? "POLLIN "  : "",(pfds[j].revents & POLLHUP) ? "POLLHUP " : "",(pfds[j].revents & POLLERR) ? "POLLERR " : "");if (pfds[j].revents & POLLIN) {ssize_t s = read(pfds[j].fd, buf, sizeof(buf));if (s == -1)errExit("read");printf("    read %zd bytes: %.*s\n",s, (int) s, buf);} else {                /* POLLERR | POLLHUP */printf("    closing fd %d\n", pfds[j].fd);if (close(pfds[j].fd) == -1)errExit("close");num_open_fds--;}}}}printf("All file descriptors closed; bye\n");exit(EXIT_SUCCESS);}

        上述代码,我给的是一个文件test1,由于代码里面时死循环,并且文件一直都是可读的,所以就一直循环,最后ctrl+c进行终止。,但是你给个目录就只打印一次。

epoll系统调用

         epoll是Linux特有的I/O复用函数。它在实现上和使用上与select,poll有很大的差异,首先,epoll使用一组函数来完成任务,而不是单个的

        epoll把用户关心的事件放到内核事件表中,而无需像select和poll那样每次调用都需要重复传入文件描述符或事件集但epoll需要额外的文件描述符来标识唯一的内核事件表

epoll_create

       #include <sys/epoll.h>int epoll_create(int size);

参数:

size:现在不起作用,提醒内核开多大空间,

返回值:

        该函数返回的文件描述符将用作其他所有epoll系统调用的一个参数。

epoll_ ctl

       #include <sys/epoll.h>int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

参数:

  • epfd:这个参数就是标识的内核事件表,epoll_create的返回值。
  • op:指定操作类型
  •         EPOLL_CTL_ADD:添加fd上注册的事件
  •         EPOLL_CTL_MOD:修改fd上注册的事件
  •         EPOLL_CTL_DEL:删除fd上注册的事件
  • fd:要操作的文件描述符
  • event:指定事件,他是epoll_event结构体指针类型。
struct epoll_event
{__uint_tevents;//epoll事件epoll_data_t data;//用户数据
}typedef struct union epoll_data
{void*ptr;int fd;uint32 u32;uint64 u64;
}epoll_data_t;

epoll支持的事件类型和poll事件类型基本相同,只需在poll事件类型的宏前面加"E".

epoll两个额外的事件类型EPOLLETEPOLLONESHOT,他们对于epoll的高效运作非常重要。

后面在介绍。 

返回值: 成返回0,失败返回-1并设置errno.

 epoll_wait

        epoll系列函数主要调用接口,它在一段超时时间内等待一组文件描述符。 

       #include <sys/epoll.h>int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

参数:

  • epfd:就是epoll_create函数的返回值。
  • timeout:与poll函数的timeout含义相同,单位毫秒
  • maxevents:最多监听多少个事件,他必须大于0。
  • events:epoll_wait函数如果检测到事件,就将所有就绪的事件从内核时间表中复制到events指向的数组中。

返回值:

        成功返回就绪的文件描述符的个数,失败返回-1并设置errno。 

 epoll简单的示例代码

相关文章:

I/O复用

I/O复用使得程序能够同时监听多个文件描述符&#xff0c;这对提高程序的性能至关重要。 举个例子&#xff1a; 就好比你天天玩手机&#xff0c;你妈为了监控你&#xff0c;在你房间安装了一个监控&#xff0c;这个监控可以实时监控你的一举一动&#xff0c;并上传到你妈手机上…...

【验证可用】解决安装SQL Server数据库时,报错“启用 windows 功能 NetFx3 时出错,错误代码:-2146498298......“的问题

目录 背景一. 报错信息1.1 报错的图片信息1.2 报错的文字信息 二. 解决报错2.1 下载 NetFx3.cab 文件2.2 执行命令 三. SQL Server 修复安装 背景 一次在阿里云服务器安装 SQL Server 2012时&#xff0c;系统报错了&#xff0c;导致安装进行不下去…通过在网上查找了多种解决方…...

STM32的SDIO接口详解

目录 1. 定义与兼容性 2. SDIO时钟 3. SDIO命令与响应 4. SDIO块数据传输 5. SDIO控制器的硬件结构 6.代码实现 1.SD初始化 2.测试SD卡的读取 3.测试SD卡的写入 STM32的SDIO&#xff08;Secure Digital Input/Output&#xff0c;安全数字输入输出&#xff09;接口是一…...

docker容器常用指令,dockerfile

docker&#xff1a;容器&#xff0c;主要是解决环境迁移的问题&#xff0c;将环境放入docker中&#xff0c;打包成镜像。 docker的基本组成&#xff1a;镜像(image)&#xff0c;容器(container)&#xff0c;仓库(repository)。镜像相当于类&#xff0c;容器相当于类的实例对象…...

C语言学习笔记 Day11(指针--下)

Day11 内容梳理&#xff1a; 目录 Chapter 7 指针 7.6 指针 & 函数 &#xff08;1&#xff09;形参改变实参的值 &#xff08;2&#xff09;字符数组作为函数参数 1&#xff09;合并字符串 2&#xff09;删掉字符串中空格 &#xff08;3&#xff09;指针作为函数返…...

(24)(24.2) Minim OSD快速安装指南(二)

文章目录 前言 6 MinimOSD-extra NG 7 替代硬件 前言 本文简要介绍了如何连接电路板。有关更多详细说明&#xff0c;请参阅 MinimOSD 项目维基(MinimOSD Project wiki)。 6 MinimOSD-extra NG 该项目位于此处(here)&#xff1b;文档位于此处(here)&#xff1b;支撑线位于此…...

GD32 MCU碰到IIC总线卡死怎么办?

大家在使用MCU IIC通信时&#xff0c;若碰到设备复位或者总线干扰等情况&#xff0c;可能会导致IIC总线卡死&#xff0c;表现上总线上SDA或者SCL其中一根线为低电平&#xff0c;IIC总线一直处于busy状态。此时若代码上一直等待总线空闲&#xff0c;则可能导致软件死机&#xff…...

算法——动态规划:0/1 背包问题

文章目录 一、问题描述二、解决方案1. DP 状态的设计2. 状态转移方程3. 算法复杂度4. 举例5. 实现6. 滚动数组6.1 两行实现6.2 单行实现6.3 优缺点 三、总结 一、问题描述 问题的抽象&#xff1a;给定 n n n 种物品和一个背包&#xff0c;第 i i i 个物品的体积为 c i c_i …...

又是奇瑞,“统一下班时间”过去不久,最近又整新活了...

奇瑞 345 345 可不是奇瑞的汽车型号&#xff0c;而是奇瑞 7 月份会议文章中提出的新策略。 简单来说&#xff0c;要提高加班效率&#xff0c;实现 3 个人干 5 个人活&#xff0c;拿 4 个人的工资&#xff0c;要把员工当成家人一样看待&#xff0c;要对他们的健康幸福负责。 前面…...

ubuntu24.04lts cmake编译 opencv4.5.4 contrib的一些问题

编译之前一定要安装好必须的库&#xff0c;否则即使提示编译成功&#xff0c;调用opencv后也可能会有问题 sudo apt-get update sudo apt-get upgradesudo apt-get install -y g sudo apt-get install -y cmake sudo apt-get install -y make sudo apt-get install…...

大数据面试SQL(三):每分钟在线直播人数

文章目录 每分钟在线直播人数 一、题目 二、分析 三、SQL实战 四、样例数据参考 每分钟在线直播人数 一、题目 有如下数据记录直播平台主播上播及下播时间&#xff0c;根据该数据计算出平台每分钟的在线直播人数。 这里用主播名称做统计&#xff0c;前提是主播名称唯一…...

python中执行mysql操作并将python脚本共享

mysql下载路径&#xff1a; ​​​​​​MySQL :: MySQL Community Downloads [root2 ~]# vim py001.py a3 b4 print(ab) print(a**2b**2) [root2 ~]# python py001.py 7 25 [root2 ~]# python3 >>> import random >>> random <module rando…...

HTTP、HTTPS、SOCKS5三种协议特点

在互联网通信中&#xff0c;HTTP、HTTPS和SOCKS5是三种至关重要的协议&#xff0c;它们各自具有独特的特点和应用场景。本文将详细探讨这三种协议的特点&#xff0c;帮助读者更好地理解它们在网络通信中的作用。 一、HTTP协议特点 HTTP&#xff08;Hypertext Transfer Protoc…...

在ubuntu、centos、openEuler安装Docker

目录 ubuntu、centos、openEuler安装Docker 1.在 Ubuntu 上安装 Docker 1. 1 更新软件包 1. 2 安装必要的依赖 1.3 添加 Docker 的 GPG 密钥 1.4 添加 Docker 仓库 1.5 更新软件包 1.6 安装 Docker 1.7 启动并启用 Docker 服务 1.8 验证安装 1.9 运行测试容器 1.10…...

公共命名空间的例子3

有这样一个句子 用x语言解释[12*3]。 在x语言中&#xff0c;不符合“先乘除后加减”&#xff0c;这个句子应该怎样解释呢&#xff1f; 第一步&#xff0c;进行词法分析&#xff0c;目的是识别出注释和字符串&#xff0c;其中可能包括任意符号&#xff0c;干扰编译过程。 第二步…...

【云存储】SDS软件定义存储,数据存储的类型与技术方案(块/文件/对象,Ceph、RBD等)

【云存储】SDS软件定义存储&#xff0c;数据存储的类型与技术方案&#xff08;块/文件/对象&#xff0c;Ceph、RBD等&#xff09; 文章目录 1、分布式存储架构&#xff08;软件定义存储SDS&#xff0c;超融合基础架构HCI&#xff09;2、存储类型&#xff08;块存储&#xff0c;…...

第31课 Scratch入门篇:小画家(舞台上画画)

小画家(舞台上画画) 故事背景: 在舞台上选择画笔和颜色,进行画画 程序原理: 这节课我们继续练习画笔功能,通过画笔功能我们设计一个小画板,碰到哪种颜色画笔就切换成哪种颜色。 开始编程 1、绘制一大一小的黑色圆形,小的命名为画笔,大的圆形命名为black(黑色) 2、鼠…...

QT UI界面之ListView

文章目录 概述源码怎么用代码qt design 小结 概述 本来把布局文件那块写了一遍&#xff0c;但是看看都跟之前那篇差不多&#xff0c;就换了一个稍微有点难度的&#xff0c;也很常用的listview来写了。来看看&#xff0c;有什么好玩的。 源码 先看下源码&#xff0c;如下&…...

freeRTOS互斥量(mutex)

目录 前言 一、互斥量概述 二、互斥量函数 1.创建 2.其他函数 三、优先级反转示例 1.概念 2.代码示例 四、优先级继承 1.概念 2.代码示例 五、递归锁 1.死锁的概念 2.自我死锁 3.函数 4.递归锁代码示例 前言 在之前的信号量中&#xff0c;我们想要实现互斥的…...

基于GeoTools使用JavaFx进行矢量数据可视化实战

目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知&#xff0c;JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然&#xff0…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...