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之后的又一款用于桌面应用的开发利器。当然࿰…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
