使用 `select` 实现文件描述符监控的深入解析与示例

文章目录

    • 0. 概述
    • 1. `select` 函数概述
    • 2. 普通文件描述符的 `select` 行为
    • 3. 监控普通文件描述符的实际应用
      • 3.1 C++ 代码示例
      • 3.2 使用 `stat` 函数监控文件修改时间
    • 结论

0. 概述

在编程中,select 函数可以用于监控多个文件描述符(包括 socket、串口和普通文件),以等待它们变为可读、可写或发生错误事件。本文将重点介绍 select 在监控普通文件描述符(句柄)时的行为,并提供实际的 C++ 代码示例。

1. select 函数概述

select 是一个系统调用函数,用于监控多个文件描述符,等待它们变为可读、可写或发生错误事件。调用 select 时,程序会阻塞,直到至少有一个描述符满足指定条件或超时。

2. 普通文件描述符的 select 行为

对于普通文件描述符,select 的行为与 socket 或串口略有不同:

  • 普通文件是否可读主要依赖于文件的当前读取位置以及文件的实际内容。
  • 如果一个普通文件已经打开且没有到达文件尾(EOF),select 会将其标记为可读状态。
  • 一旦文件被读取到 EOF,之后的 select 调用(若没有新的数据写入文件)将不会将其标记为可读,除非文件被重新写入或文件指针被重置。

3. 监控普通文件描述符的实际应用

3.1 C++ 代码示例

以下是一段 C++ 代码,演示了如何使用 select 监控一个普通文件。当文件内容发生变化时,程序会调用 onFileChange 回调函数:

#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#include <iostream>
#include <vector>static off_t lastReadPosition = 0;void onFileChange(FILE* file);int main() {const char* filePath = "/home/feng/workspace/test_select_file/example.txt";FILE* file = fopen(filePath, "r");if (!file) {perror("无法打开文件");return 1;}int fileFd = fileno(file);if (fileFd == -1) {perror("无法获取文件描述符");fclose(file);return 1;}fd_set rfds;FD_ZERO(&rfds);FD_SET(fileFd, &rfds);struct timeval tv = {1, 0};while (true) {fd_set rfdsCopy = rfds;int retval = select(fileFd + 1, &rfdsCopy, nullptr, nullptr, &tv);if (retval == -1) {perror("select failed");break;} else if (retval) {if (FD_ISSET(fileFd, &rfdsCopy)) {fseek(file, 0, SEEK_END);onFileChange(file);}}}fclose(file);return 0;
}void onFileChange(FILE* file) {off_t currentPosition = ftell(file);if (currentPosition != lastReadPosition) {std::cout << "文件内容发生变化,触发回调函数!" << std::endl;lastReadPosition = currentPosition;}
}

这段代码通过 select 函数监控文件描述符的变化,当文件内容发生变化时,调用 onFileChange 函数进行处理。

3.2 使用 stat 函数监控文件修改时间

另一个示例展示了如何使用 stat 函数监控文件的最后修改时间:

#include <sys/stat.h>
#include <unistd.h>
#include <ctime>
#include <iostream>void printLastModificationTime(const char* filePath) {struct stat fileStats;if (stat(filePath, &fileStats) == 0) {std::cout << "File: " << filePath << " last modified at: " << std::asctime(std::localtime(&fileStats.st_mtime));} else {perror("Error getting file status");}
}int main() {const char* filePath = "/tmp/example.txt";printLastModificationTime(filePath);std::cout << "Watching for changes...\n";while (true) {sleep(1);struct stat currentStats;if (stat(filePath, &currentStats) == 0) {time_t currentTime = currentStats.st_mtime;static time_t previousTime = currentTime;if (currentTime != previousTime) {std::cout << "File modified! New time: ";printLastModificationTime(filePath);previousTime = currentTime;}} else {perror("Error in stat during watch");break;}}return 0;
}

结论

本文介绍了如何使用 select 函数监控普通文件描述符,并提供了实际的 C++ 代码示例,展示了文件内容变化检测和文件最后修改时间监控的实现方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/855950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【尚庭公寓SpringBoot + Vue 项目实战】登录管理(十八)

【尚庭公寓SpringBoot Vue 项目实战】登录管理&#xff08;十八&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】登录管理&#xff08;十八&#xff09;1、登录业务介绍2、接口开发2.1、获取图形验证码2.2、登录接口2.3、获取登录用户个人信息 1、登录业务介绍 登…

Memcached原理及使用详解

文章目录 Memcached原理1. 内存存储2. 分布式缓存3. 键值对存储4. 过期策略5. 淘汰策略 Memcached的优缺点优点1. 高性能2. 分布式缓存3. 简单的键值对存储4. 可扩展性5. 灵活性 缺点1. 数据持久化问题2. 安全性问题3. 内存限制4. 依赖外部存储5. 缺乏复杂查询支持 Memcached使…

SpringCloud Netflix和SpringCloud Alibaba核心组件

1.SpringCloud Netflix组件 1.1 Netflix Eureka-服务注册发现 Eureka 是一种用于服务发现 的组件&#xff0c;它是一个基于 REST 的服务&#xff0c;用于定位运行在 AWS 弹性计算云&#xff08;EC2&#xff09;中的中间层服务&#xff0c;以便它们可以相互通讯。 注册&#xf…

day14-226.翻转二叉树+101. 对称二叉树+104.二叉树的最大深度

一、226.翻转二叉树 题目链接&#xff1a;https://leetcode.cn/problems/invert-binary-tree/ 文章讲解&#xff1a;https://programmercarl.com/0226.%E7%BF%BB%E8%BD%AC%E4%BA%8C%E5%8F%89%E6%A0%91.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE 视频讲解&#xff1…

微信小程序学习(八):behaviors代码复用

小程序的 behaviors 方法是一种代码复用的方式&#xff0c;可以将一些通用的逻辑和方法提取出来&#xff0c;然后在多个组件中复用&#xff0c;从而减少代码冗余&#xff0c;提高代码的可维护性。 如果需要 behavior 复用代码&#xff0c;需要使用 Behavior() 方法&#xff0c…

C++ —— unordered_set、unordered_map的介绍及使用

目录 unordered系列关联式容器 unordered_set的介绍 unordered_set的使用 unordered_set的定义方式 unordered_set接口的使用 unordered_multiset unordered_map的介绍 unordered_map的使用 unordered_map的定义方式 unordered_map接口的使用 unordered_multimap …

避免在使用Element-UI el-form时的resetFields陷阱

避免在使用Element-UI el-form时的resetFields陷阱 在使用Vue.js结合Element-UI开发表单时&#xff0c;el-form的resetFields方法是一个常用的功能&#xff0c;用于重置表单项到初始状态。然而&#xff0c;这个方法在某些情况下可能导致一些不易察觉的问题。本文将分享一个实际…

第二十九章 使用 MTOM 进行附件 - Web 服务和 Web 客户端的默认行为

文章目录 第二十九章 使用 MTOM 进行附件 - Web 服务和 Web 客户端的默认行为Web 服务和 Web 客户端的默认行为强制响应为 MTOM 包对 WSDL 的影响 强制请求作为 MTOM 包对 WSDL 的影响 第二十九章 使用 MTOM 进行附件 - Web 服务和 Web 客户端的默认行为 Web 服务和 Web 客户端…

智慧校园发展趋势:2024年及未来教育科技展望

展望2024年及未来的教育科技领域&#xff0c;智慧校园的发展正引领着一场教育模式的深刻变革&#xff0c;其核心在于更深层次地融合技术与教育实践。随着人工智能技术的不断成熟&#xff0c;个性化学习将不再停留于表面&#xff0c;而是深入到每个学生的个性化需求之中。通过精…

密钥管理简介

首先我们要知道什么是密钥管理&#xff1f; 密钥管理是一种涉及生成、存储、使用和更新密钥的过程。 密钥的种类 我们知道&#xff0c;对称密码主要包括分组密码和序列密码。但有时也可以将杂凑函数和消息认证码划分为这一类&#xff0c;将它们的密钥称为对称密钥&#xff1b;…

Clickhouse监控_使用Prometheus+Grafana来监控Clickhouse服务和性能指标

官方文档https://clickhouse.com/docs/zh/operations/monitoring 建议使用PrometheusGrafana组合监控Clickhouse服务和性能指标 1、把prometheus的clickhouse_exporter下载到Clickhouse服务器&#xff0c;查找prometheus的clickhouse_exporter参见https://prometheus.io/docs…

白酒:酒文化的地域特色与差异

中国的白酒文化&#xff0c;作为一种深深植根于人们生活中的文化现象&#xff0c;其发展历程深受地域特色的影响&#xff0c;从而形成了丰富多样的地域特色与差异。云仓酒庄的豪迈白酒&#xff0c;作为中国白酒的品牌&#xff0c;其背后所蕴含的地域特色与差异更是值得我们去探…

在 Ubuntu 18.04.4 LTS上安装 netmap

文章目录 步骤运行配置文件编译安装使用netmap 步骤 sudo su sudo apt-get update sudo apt install build-essential sudo apt-get install -y git sudo apt-get install -y linux-headers-$(uname -r)rootVM-20-6-ubuntu:/home/ubuntu/netmap/LINUX# git clone https://gith…

外观模式(大话设计模式)C/C++版本

外观模式 C #include <iostream> using namespace std;class stock1 { public:void Sell(){cout << "股票1卖出" << endl;}void Buy(){cout << "股票1买入" << endl;} };class stock2 { public:void Sell(){cout << …

el-cascader 支持多层级,多选(可自定义限制数量),保留最后一级

多功能的 el-cascader 序言&#xff1a;最近遇到一个需求关于级联的&#xff0c;有点东西&#xff0c;这里是要获取某个产品类型下的产品&#xff0c;会存在产品类型和产品在同一级的情况&#xff0c;但是产品类型不能勾选&#xff1b; 情况1&#xff08;二级菜单是产品&…

【杂记-浅谈等价路由】

浅谈等价路由 一、等价路由概述二、等价路由的特点1、负载均衡2、链路备份3、路由收敛快 三、等价路由的应用场景四、等价路由的配置与优化五、等价路由的挑战与发展 一、等价路由概述 Equal-Cost Multipath Routing&#xff0c;简称ECMP&#xff0c;即等价路由&#xff0c;指…

干货分享——AB站帮你解决独立站收款难题

目前&#xff0c;国内已经有抖音、拼多多和淘宝平台推出“仅退款”售后服务&#xff0c;无疑是加剧了原本就在疯狂打价格战的国内电商的严峻现状&#xff0c;使得商家不得不担心被顾客“薅羊毛”。在国内电商环境严重“内卷”的情况下&#xff0c;拓宽海外市场不失为一大妙计。…

【mysql】排错和调优

通用的一些排错方法。 1、查看进程信息 mysql> show full processlist;mysql> show processlist; 2、information_schema information_schema这张数据表保存了MySQL服务器所有数据库的信息。如数据库名&#xff0c;数据库的表&#xff0c;表栏的数据类型与访问权限等。…

DDP算法之反向传播(Backward Pass)

DDP算法反向传播 在DDP(Differential Dynamic Programming)算法中,反向传播(Backward Pass)是关键步骤之一。这个步骤的主要目的是通过动态规划递归地计算每个时间步上的值函数和控制策略,以便在前向传播(Forward Pass)中使用。 反向传播的目标 反向传播的主要目标是…

AD层次原理图绘制

一、在原理图中添加端口 二、添加层次图 三、更新层次图 四、也可以先画层次图&#xff0c;再绘制原理图&#xff0c;这里就不做演示了