C++ 异步读本地文件,不堵塞主线程

在 C++ 中,如果希望异步读取本地文件而不阻塞主线程,可以使用多线程或异步 I/O 操作。常见的方法是通过使用标准库的 std::thread 进行多线程操作,或者通过类似 Boost.Asio 的异步 I/O 库来实现非阻塞操作。由于 C++ 标准库本身并不直接支持异步文件 I/O,所以这里我们将使用多线程来模拟异步文件读取。

方法 1: 使用 std::thread 来实现异步读取文件

使用 std::thread 可以在后台启动一个线程来读取文件,从而避免阻塞主线程。读取完成后,可以使用回调函数或 std::future 获取结果。

示例代码:

#include <iostream>
#include <fstream>
#include <thread>
#include <vector>
#include <string>
#include <functional>// 异步读取文件函数
void async_read_file(const std::string& file_path, std::function<void(const std::vector<char>&)> callback) {std::thread([file_path, callback]() {// 打开文件std::ifstream file(file_path, std::ios::binary);if (!file.is_open()) {std::cerr << "Failed to open the file!" << std::endl;return;}// 读取文件内容到内存中std::vector<char> file_data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());// 调用回调函数处理读取的数据callback(file_data);file.close();}).detach();  // 使用detach让线程在后台运行,不阻塞主线程
}int main() {std::string file_path = "test.txt"; // 替换成你的文件路径// 异步读取文件async_read_file(file_path, [](const std::vector<char>& data) {// 读取完成后的回调函数,处理文件数据std::cout << "File read successfully, size: " << data.size() << " bytes." << std::endl;// 打印前100字节作为示例std::cout.write(data.data(), std::min<size_t>(100, data.size()));std::cout << std::endl;});// 主线程继续执行其他任务std::cout << "Main thread is free to do other work..." << std::endl;// 为了演示,主线程等待一会儿以便异步线程完成std::this_thread::sleep_for(std::chrono::seconds(2));return 0;
}

说明:

  • async_read_file 函数接收文件路径和回调函数。在新线程中执行文件读取,读取完成后,回调函数会被调用处理文件数据。
  • std::thread 用于在后台启动线程读取文件。通过 detach() 将线程与主线程分离,允许它在后台执行。
  • 主线程继续执行其他任务,避免了阻塞。

方法 2: 使用 Boost.Asio 异步 I/O 操作

如果希望利用异步 I/O 操作而不使用线程,也可以使用 Boost.Asio 来模拟文件读取的异步操作。虽然 Boost.Asio 是设计来处理网络 I/O 的,但你可以通过封装文件读取操作,将其作为异步任务来执行。

示例代码:

#include <iostream>
#include <fstream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>class AsyncFileReader {
public:AsyncFileReader(boost::asio::io_service& io_service, const std::string& file_path): io_service_(io_service), file_path_(file_path), buffer_(1024) {}// 启动异步读取文件操作void start() {std::ifstream file(file_path_, std::ios::binary);if (!file.is_open()) {std::cerr << "Failed to open the file!" << std::endl;return;}// 读取文件到缓冲区file.read(buffer_.data(), buffer_.size());// 完成读取后调用异步操作的回调函数io_service_.post(boost::bind(&AsyncFileReader::on_file_read, this, file.gcount()));}private:// 文件读取完成后的回调函数void on_file_read(std::size_t bytes_read) {std::cout << "File read successfully, bytes read: " << bytes_read << std::endl;std::cout.write(buffer_.data(), bytes_read);  // 打印读取的内容std::cout << std::endl;}boost::asio::io_service& io_service_;std::string file_path_;std::vector<char> buffer_;  // 用于存储读取的数据
};int main() {try {boost::asio::io_service io_service;std::string file_path = "test.txt";  // 替换为你的文件路径// 创建异步文件读取对象AsyncFileReader file_reader(io_service, file_path);file_reader.start();// 运行异步操作io_service.run();std::cout << "Main thread is free to do other work..." << std::endl;} catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
}

说明:

  • Boost.Asioio_service 被用来调度异步任务。在这个例子中,文件读取操作是同步的,但它的回调是通过 io_service.post 来调度的。文件读取完成后,on_file_read 回调函数会被触发,处理文件内容。
  • 这个例子使用了 boost::bind 来将成员函数作为回调函数传递。通过 boost::asio::io_service 管理异步操作,尽管文件 I/O 不是直接异步的,但它模拟了异步执行的模式。

总结:

  • 方法 1:使用 std::thread 是一种简单的方式,利用多线程实现异步读取文件。每次读取都启动一个新的线程,这对于简单的任务是可行的,但如果有大量并发操作,可能会导致线程过多,进而影响性能。
  • 方法 2:使用 Boost.Asio 可以模拟异步操作,适用于希望将所有异步操作统一管理的场景,尤其是在事件驱动和网络编程中。但由于标准 C++ 库并不直接支持异步文件 I/O,Boost.Asio 只是通过异步任务调度模拟了这种行为。

在实际应用中,选择使用哪种方式取决于具体需求,例如是否需要更复杂的异步 I/O 操作或更好的线程管理。

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

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

相关文章

golang通用后台管理系统09(系统操作日志记录)

1.日志工具类 package log/**** 日志记录 wangwei 2024-11-18 15:30*/ import ("log""os""path/filepath""time" )// 获取以当前日期命名的日志文件路径 func getLogFilePath() string {currentDate : time.Now().Format("2006-…

迁移学习理论与应用

迁移学习&#xff08;Transfer Learning&#xff09;是一种机器学习技术&#xff0c;旨在将一个任务&#xff08;源任务&#xff09;上学到的知识迁移到另一个相关但不完全相同的任务&#xff08;目标任务&#xff09;上&#xff0c;从而提高目标任务的学习效果。这种方法的核心…

Azure Kubernetes Service (AKS)资源优化策略

针对Azure Kubernetes Service (AKS)的资源优化策略&#xff0c;可以从多个维度进行考虑和实施&#xff0c;以提升集群的性能、效率和资源利用率。以下是一些关键的优化策略&#xff1a; 一、 Pod资源请求和限制 设置Pod请求和限制&#xff1a;在YAML清单中为所有Pod设置CPU和…

Vue3 虚拟列表组件库 virtual-list-vue3 的使用

Vue3 虚拟列表组件库 virtual-list-vue3 的基本使用 分享个人写的一个基于 Vue3 的虚拟列表组件库&#xff0c;欢迎各位来进行使用与给予一些更好的建议&#x1f60a; 概述&#xff1a;该组件组件库用于提供虚拟化列表能力的组件&#xff0c;用于解决展示大量数据渲染时首屏渲…

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下&#xff1a; 1.实现文件夹的下载和删除&#xff0c;网上很多资料都是单独对某个路径的文件操作的&#xff0c;并不能对文件夹操作 2.实现目标机中含中文名称自动转码&#xff0c;有些系统编码方式不同&#xff0c;下载出来的文件会乱码 3.实现ftp功能…

SpringBoot登录功能实现思路(验证码+拦截器+jwt)

总括 用户输入用户名和密码和验证码即可进行登录 验证码 VerifyCode&#xff1a;生成验证码的工具类 /*** 生成验证码的工具类*/ public class VerifyCode {private int w 70;//设置缓冲区的宽private int h 35;//设置缓冲区的宽private Random r new Random();//从字体…

小米路由器用外网域名访问管理界面

本文在Redmi AX3000 (RA81)设置&#xff0c;其他型号路由器的管理界面端口可能各不相同。 开始之前需要保证路由器SSH功能正常&#xff0c;如果没有SSH可以参考这里。 1. 给WAN口开放80端口 可以通过下载mixbox的firewall插件或者其他防火墙插件开放端口。 2. 把域名解析到路…

杰发科技AC7801——ADC定时器触发的简单使用

使用场景 在需要多次采样结果的情况下&#xff0c;比如1s需要10w次的采样结果&#xff0c;可以考虑使用定时器触发采样&#xff0c;定时器设置多少的时间就会多久采样转换一次。 再加上使用dma&#xff0c;采样的结果直接放在dma的数组里面。 实现了自动采样&#xff0c;自动…

pytest结合allure做接口自动化

这是一个采用pytest框架&#xff0c;结合allure完成接口自动化测试的项目&#xff0c;最后采用allure生成直观美观的测试报告&#xff0c;由于添加了allure的特性&#xff0c;使得测试报告覆盖的内容更全面和阅读起来更方便。 1. 使用pytest构建测试框架&#xff0c;首先配置好…

现代分布式系统新法宝:基于单元的架构

- 前言 - 数十年来&#xff0c;IT 业界一直在努力掌握分布式系统。然而&#xff0c;随着系统日益复杂&#xff0c;给开发数字产品的组织带来巨大挑战。可以说&#xff0c;分布式系统最棘手的方面之一是面对故障时的可靠性&#xff0c;特别是现代分布式系统使用大量物理与虚拟资…

C#桌面应用制作计算器

C#桌面应用制作简易计算器&#xff0c;可实现数字之间的加减乘除、AC按键清屏、Del按键清除末尾数字、/-按键取数字相反数、%按键使数字缩小100倍、按键显示运算结果等...... 页面实现效果 功能实现 布局 计算器主体使用Panel容器&#xff0c;然后将button控件排列放置Pane…

python: generator IDAL and DAL using sql server 2019

其它数据库也是一样的思维方式 create IDAL # encoding: utf-8 # 版权所有 2024 ©涂聚文有限公司 # 许可信息查看&#xff1a;言語成了邀功盡責的功臣&#xff0c;還需要行爲每日來值班嗎 # 描述&#xff1a; # Author : geovindu,Geovin Du 涂聚文. # IDE : P…

鲸鱼机器人和乐高机器人的比较

鲸鱼机器人和乐高机器人各有其独特的优势和特点&#xff0c;家长在选择时可以根据孩子的年龄、兴趣、经济能力等因素进行综合考虑&#xff0c;选择最适合孩子的教育机器人产品。 优势 鲸鱼机器人 1&#xff09;价格亲民&#xff1a;鲸鱼机器人的产品价格相对乐高更为亲民&…

探究IOC容器刷新环节初始化前的预处理

目录 一、IOC容器的刷新环节快速回顾 二、初始化前的预处理prepareRefresh源码分析 三、初始化属性源 &#xff08;一&#xff09;GenericWebApplicationContext初始化属性源 &#xff08;二&#xff09;StaticWebApplicationContext初始化属性源 四、初始化早期事件集合…

【Java SE】PreparedStatement

PreparedStatement 是一个接口&#xff0c;它继承自 Statement&#xff0c;用于预编译 SQL 语句。简单来说&#xff0c;PreparedStatement 是 JDBC 提供的一个对象&#xff0c;用于执行 SQL 语句。它的重要功能是帮助防止 SQL 注入攻击&#xff0c;并提高执行效率。 SQL 注入问…

集群聊天服务器(7)数据模块

目录 Mysql数据库代码封装头文件与源文件 Mysql数据库代码封装 业务层代码不要直接写数据库&#xff0c;因为业务层和数据层的代码逻辑也想完全区分开。万一不想存储mysql&#xff0c;想存redis的话&#xff0c;就要改动大量业务代码。解耦合就是改起来很方便。 首先需要安装m…

数造科技亮相第26届高交会并接受媒体采访,以数据智能赋能未来

11 月 14 日至 16 日&#xff0c;第二十六届中国国际高新技术成果交易会&#xff08;简称“高交会”&#xff09;在深圳成功举办。本届大会以“科技引领发展&#xff0c;产业融合聚变”为主题&#xff0c;汇聚了全球最新的科技成果&#xff0c;打造了一场科技界的盛大聚会。 在…

C#获取视频第一帧_腾讯云媒体处理获取视频第一帧

一、 使用步骤&#xff1a; 第一步、腾讯云开启万象 第二步、安装Tencent.QCloud.Cos.Sdk 包 第三步、修改 腾讯云配置 图片存储目录配置 第四步、执行获取图片并保存 二、封装代码 using System.Text; using System.Threading.Tasks;using COSXML.Model.CI; using COSXML.A…

概念解读|K8s/容器云/裸金属/云原生...这些都有什么区别?

随着容器技术的日渐成熟&#xff0c;不少企业用户都对应用系统开展了容器化改造。而在容器基础架构层面&#xff0c;很多运维人员都更熟悉虚拟化环境&#xff0c;对“容器圈”的各种概念容易混淆&#xff1a;容器就是 Kubernetes 吗&#xff1f;容器云又是什么&#xff1f;容器…

吴恩达深度学习笔记:序列模型(Sequence Models) 1.3-1.4

目录 第五门课 序列模型(Sequence Models)第一周 循环序列模型&#xff08;Recurrent Neural Networks&#xff09;1.3 循环神经网络模型&#xff08;Recurrent Neural Network Model&#xff09;1.4 通过时间的反向传播&#xff08;Backpropagation through time&#xff09; …