讲师中心 微信公众号
AI工具推荐 视频效率加速

C++如何实现带超时的批量文件操作?(并行copy/delete监控)

胖墨姑娘_8488

胖墨姑娘_8488

发布时间:2026-02-19 11:31:13

|

622人浏览过

|

来源于php中文网

原创

不能直接套用std::async+std::future::wait_for实现真正超时取消;必须采用协作式中断:分块I/O+轮询std::stop_token,C++20的std::jthread是最优解。

c++如何实现带超时的批量文件操作?(并行copy/delete监控)

std::async + std::future::wait_for 能直接套用吗?

不能。直接对 std::async 返回的 std::future 调用 wait_for 只能阻塞等待任务结束,但无法中断正在执行的系统调用(比如 CopyFileEx 或 unlink)。一旦底层 I/O 卡住(如网络盘断连、权限挂起),任务就真卡死了,超时形同虚设。

真正可行的思路是:把耗时操作拆成可协作中断的片段,并在关键点轮询中断信号。C++20 的 std::jthread 和 std::stop_token 是目前最干净的解法。

  • 用 std::jthread 启动每个文件操作,传入 std::stop_token
  • 在每次读/写/删除前检查 token.stop_requested()
  • 对 CopyFileEx(Windows)或 sendfile/read+write(Linux)做分块处理,每 copy 64KB 就查一次 token
  • 不要依赖 std::future::wait_for 做“超时控制”,它只管等待,不管取消

Windows 下 CopyFileEx 如何配合超时和取消?

CopyFileEx 本身支持回调函数和取消句柄,但它的取消是异步的——调用 CancelSynchronousIo 后仍需等待线程退出,且该函数只能取消当前线程发起的 I/O,不适用于线程池场景。

更稳的做法是不用它的原生取消,改用“协作式取消”:

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 把 CopyFileEx 改为手动循环:CreateFile → 分块 ReadFile+WriteFile → 每次调用后检查 stop_token
  • 用 SetFileCompletionNotificationModes 配合 I/O 完成端口(IOCP)也能实现非阻塞+可取消,但复杂度陡增,小批量操作没必要
  • 注意 CopyFileEx 的 lpProgressRoutine 回调里不能直接 throw 或 longjmp,否则可能破坏系统状态
  • 若必须用 CopyFileEx,至少把超时逻辑放在外层:启动后开一个 std::jthread 等待,超时则调用 CancelSynchronousIo 并 CloseHandle 源/目标文件句柄(有风险,慎用)

Linux 下用 sendfile 还是 read/write?怎么插中断点?

sendfile 性能好,但不支持用户态中断——它是一条内核原子路径,调用期间无法响应 stop_token。一旦源文件被其他进程锁住或 NFS 挂起,就彻底卡死。

所以生产环境建议退回到带缓冲的 read+write 循环:

  • 用 std::vector<char> buf(64 * 1024)</char> 做缓冲区,每次 read(fd_in, buf.data(), buf.size())
  • 读完立刻检查 token.stop_requested(),返回 std::errc::operation_canceled
  • 写之前也检查一次,避免写一半被中断
  • read 返回 0 表示 EOF;返回 -1 且 errno == EINTR 可重试;其他错误(如 EACCES)直接报错
  • 别用 splice——它和 sendfile 一样不可中断,且跨文件系统时会自动 fallback 到 copy,行为不一致

delete 操作怎么做到可超时、可取消?

std::filesystem::remove 是同步阻塞的,遇到只读文件、挂载点或权限问题就会卡住,没有内置超时。更麻烦的是,它不接受 cancellation token。

解决方案不是“包装一层”,而是提前规避:

  • 删前先用 std::filesystem::status 检查类型和权限,跳过目录或只读项(或按策略抛错)
  • 对普通文件,用 unlinkat(AT_FDCWD, path.c_str(), 0) 替代 remove,它失败更快(尤其在 NFS 上)
  • 如果要删整个目录树,必须自己递归 + 每层检查 stop_token,不能依赖 std::filesystem::remove_all
  • 注意:Windows 下 DeleteFile 对正在被打开的文件会失败并返回 ERROR_SHARING_VIOLATION,这不是卡住,是明确错误,应重试或跳过

真正的难点从来不在“怎么写超时”,而在于 I/O 操作本身的不可中断性——所有看似“加个 timeout 参数”的方案,底层都得靠分块+轮询+早检查。漏掉任意一处检查点,超时就失效。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

15006

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1765

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

4177

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

6361

2024.03.01

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4678

2023.08.10

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

3431

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1025

2023.12.29

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3419

2023.07.26

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn