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两个额外的事件类型EPOLLET和EPOLLONESHOT,他们对于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复用使得程序能够同时监听多个文件描述符,这对提高程序的性能至关重要。 举个例子: 就好比你天天玩手机,你妈为了监控你,在你房间安装了一个监控,这个监控可以实时监控你的一举一动,并上传到你妈手机上…...

【验证可用】解决安装SQL Server数据库时,报错“启用 windows 功能 NetFx3 时出错,错误代码:-2146498298......“的问题
目录 背景一. 报错信息1.1 报错的图片信息1.2 报错的文字信息 二. 解决报错2.1 下载 NetFx3.cab 文件2.2 执行命令 三. SQL Server 修复安装 背景 一次在阿里云服务器安装 SQL Server 2012时,系统报错了,导致安装进行不下去…通过在网上查找了多种解决方…...

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

docker容器常用指令,dockerfile
docker:容器,主要是解决环境迁移的问题,将环境放入docker中,打包成镜像。 docker的基本组成:镜像(image),容器(container),仓库(repository)。镜像相当于类,容器相当于类的实例对象…...

C语言学习笔记 Day11(指针--下)
Day11 内容梳理: 目录 Chapter 7 指针 7.6 指针 & 函数 (1)形参改变实参的值 (2)字符数组作为函数参数 1)合并字符串 2)删掉字符串中空格 (3)指针作为函数返…...

(24)(24.2) Minim OSD快速安装指南(二)
文章目录 前言 6 MinimOSD-extra NG 7 替代硬件 前言 本文简要介绍了如何连接电路板。有关更多详细说明,请参阅 MinimOSD 项目维基(MinimOSD Project wiki)。 6 MinimOSD-extra NG 该项目位于此处(here);文档位于此处(here);支撑线位于此…...

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

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

又是奇瑞,“统一下班时间”过去不久,最近又整新活了...
奇瑞 345 345 可不是奇瑞的汽车型号,而是奇瑞 7 月份会议文章中提出的新策略。 简单来说,要提高加班效率,实现 3 个人干 5 个人活,拿 4 个人的工资,要把员工当成家人一样看待,要对他们的健康幸福负责。 前面…...

ubuntu24.04lts cmake编译 opencv4.5.4 contrib的一些问题
编译之前一定要安装好必须的库,否则即使提示编译成功,调用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实战 四、样例数据参考 每分钟在线直播人数 一、题目 有如下数据记录直播平台主播上播及下播时间,根据该数据计算出平台每分钟的在线直播人数。 这里用主播名称做统计,前提是主播名称唯一…...

python中执行mysql操作并将python脚本共享
mysql下载路径: 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三种协议特点
在互联网通信中,HTTP、HTTPS和SOCKS5是三种至关重要的协议,它们各自具有独特的特点和应用场景。本文将详细探讨这三种协议的特点,帮助读者更好地理解它们在网络通信中的作用。 一、HTTP协议特点 HTTP(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语言中,不符合“先乘除后加减”,这个句子应该怎样解释呢? 第一步,进行词法分析,目的是识别出注释和字符串,其中可能包括任意符号,干扰编译过程。 第二步…...

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

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

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

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

基于GeoTools使用JavaFx进行矢量数据可视化实战
目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知,JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然࿰…...

zabbix的setup无法进入第二步
注意-部署时,报错要看的日志不止一个,php日志的报错也要看的,nginx接收到请求后是转发到php-fpm的 [rootweb01-84-41 ~]# chmod -R 777 /var/lib/php/session chmod: 无法访问"/var/lib/php/session": 没有那个文件或目录 [rootweb…...

代码随想录算法训练营第四十六天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇
一、115. 不同的子序列 题目链接:115. 不同的子序列 - 力扣(LeetCode) 文章讲解:代码随想录 (programmercarl.com)——115. 不同的子序列 视频讲解:动态规划之子序列,为了编辑距离做铺垫 | LeetCode&#x…...

宝塔安装nginx失败报错“检测到系统组件wget不存在,无法继续安装”
宝塔安装nginx失败报错“检测到系统组件wget不存在,无法继续安装” 问题描述解决方案 问题描述 在宝塔中安装lnmp环境时,安装nginx失败报错:检测到系统组件wget不存在,无法继续安装 如下图所示 通过检查发现系统是已经安装了wge…...

C++之运算符重载系列深入学习:从入门到精通!
为什么需要对运算符进行重载 C预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其…...

国赛分析。。。。
山东 6散落2两元素 浙江 8散落两元素 安徽不公布 4散落2元素 120s 华南 8散落两元素 西部 8散落两元素 华北 8 2.。。。 华东 东北 路边6张两元素...

无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案
无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案 1.Dify 简介 1.1 功能情况 Dify,一款引领未来的开源大语言模型(LLM)应用开发平台,革新性地融合了后端即服务(Backend as a Service,BaaS)与LLMOps的精髓,为开发者铺…...

PLSQL导入导出ORACLE数据提示失败问题修改PLSQL配置
oracle中plsql导入提示无法导入问题 1.首先看下是否环境变量已经配置(具体配置看下面环境变量配置) 2.plsql数据导入中tools-->Preferences中配置如下框中的内容 3.设置 tnsnames.ora文件中看下是否设置有问题 4.PLSQL乱码问题 NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16…...

从Shift+F6到雪花算法:IDEA开发中的那些坑与解法
在日常开发中,提升代码质量和开发效率是每个开发者追求的目标。作为 Java 开发者常用的集成开发环境,IntelliJ IDEA 提供了丰富的功能与快捷键,帮助我们更快速、更高效地完成日常工作。然而,即便是如此强大的工具,也会…...

Linux知识点总结
学习目标 常见的快捷键 Linux 是一个开源的类 Unix 操作系统,广泛应用于服务器、桌面和嵌入式系统。以下是一些重要的 Linux 知识点总结: 基础概念 文件系统:Linux 使用层次化的文件系统结构,根目录为 /,其他目录如 …...

Gradio 快速开发网页应用
Gradio 是一个开源的 Python 框架,可以快速开发页面,Gradio 主要用于 AI 模型 Demo 的开发,通过几行代码可以快速生成一个 Web Demo,由于 AI 算法工程师使用的都是 Python 语言,使用 Python 开发 Demo 会相对简单&…...