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

c++怎么在Windows下利用命名管道实现高性能跨进程的文件传输【进阶】

冬辰姑娘_1003

冬辰姑娘_1003

发布时间:2026-03-25 19:15:46

|

134人浏览过

|

来源于php中文网

原创

命名管道传大文件卡在WriteFile是因为字节流模式+64KB缓冲区限制导致阻塞;应改用消息模式分块、异步I/O、边写边读,并用TransmitFile零拷贝优化,配合协议头与校验确保完整性。

c++怎么在windows下利用命名管道实现高性能跨进程的文件传输【进阶】

命名管道传输大文件时为什么卡在 WriteFile 不返回?

因为默认管道模式是字节流(PIPE_TYPE_BYTE),且缓冲区有限(通常 64KB),WriteFile 会阻塞直到对方调用 ReadFile 消费数据,或者写满内核缓冲区。跨进程传 GB 级文件时,若接收端没及时读、或网络/磁盘慢,发送端就卡住。

解决办法是:改用消息模式 + 合理分块 + 异步 I/O:

  • 创建管道时指定 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,避免粘包,但注意:消息模式单条上限 64KB,超长会被截断
  • 发送端拆成 ≤64KB 的 std::vector<char></char> 分块,每块单独调用 WriteFile
  • 务必用 FILE_FLAG_OVERLAPPED 创建句柄,配合 GetOverlappedResult 或 IOCP,否则阻塞式写在大文件下极易拖垮整个线程
  • 接收端不能等“全部写完再读”,必须边写边读——启动独立读线程,持续调用 ReadFile 并写入目标文件

CreateNamedPipe 的 nMaxInstances 设成 1 还是 255?

这不是并发连接数的自由选择,而是和你的通信模型强绑定。设成 1 表示“严格一对一”,第二个客户端连上来会直接被 ConnectNamedPipe 拒绝;设成 255 是为了支持“服务端复用同一管道名,轮流服务多个客户端”,但前提是每次服务完必须调用 DisconnectNamedPipe,再重新 ConnectNamedPipe 等待下一个。

文件传输场景下,几乎总是选 1:

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

  • 传输过程需要稳定上下文(如已协商的压缩算法、校验方式),多实例共享同一管道名会导致状态混乱
  • Windows 内核对每个实例分配独立缓冲区,设太高反而浪费内存,且无实际并发收益
  • 如果真需要一对多分发文件,应该由主服务进程创建多个独立管道(如 \.pipe ile_xfer_001、\.pipe ile_xfer_002),而不是靠 nMaxInstances 混用

为什么用 TransmitFile 替代循环 ReadFile+WriteFile?

因为绕过用户态内存拷贝。传统方式要把文件内容从磁盘读到用户缓冲区,再从缓冲区写进管道内核缓冲区,两次 memcpy;而 TransmitFile 让内核直接把文件映射页链表接续到管道发送队列,零拷贝,实测 1GB 文件快 30%–50%。

C++14
C++14

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

下载

但要注意限制条件:

  • 只支持同步句柄(不能带 FILE_FLAG_OVERLAPPED),所以得配专用线程,不能和异步逻辑混用
  • 源文件句柄必须是 GENERIC_READ 打开,且支持 FILE_FLAG_SEQUENTIAL_SCAN(提升预读效率)
  • 目标句柄必须是命名管道或套接字,且处于已连接状态(ConnectNamedPipe 返回 true 后)
  • 别忘了加 TF_USE_KERNEL_APC 标志,否则在高负载下可能触发 APC 注入延迟

示例关键调用:TransmitFile(hPipe, hFile, liFileSize.QuadPart, 0, nullptr, nullptr, TF_USE_KERNEL_APC)

接收端用 ReadFile 读到 0 字节就代表传完了?

不是。命名管道关闭时,ReadFile 才返回 0;但发送端可能只是暂时停顿、网络抖动、或对方进程卡住。盲目按 0 字节结束,会导致文件截断。

正确做法是双方约定协议头:

  • 发送端先写 8 字节 uint64_t file_size,再发原始数据
  • 接收端先用循环 ReadFile 确保读满 8 字节,解析出总长度
  • 之后累计读取字节数,等于 file_size 时才关闭目标文件句柄
  • 额外加一层校验:发送端末尾追一个 32 位 crc32,接收端验证失败则删除临时文件并报错

别依赖 EOF 或错误码判断完成——管道没有“文件结束符”概念,只有连接断开或写端关闭。

最易被忽略的是缓冲区生命周期管理:所有 OVERLAPPED 结构体必须在对应 I/O 完成前保持有效,不能放在栈上然后函数返回;异步读写回调里释放内存前,务必检查 GetLastError() == ERROR_IO_INCOMPLETE 是否仍存在未完成操作。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

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

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

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

WorkBuddy

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

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

DeepSeek

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

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

4874

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5031

2025.07.04

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6087

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2568

2023.08.10

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

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

4338

2023.08.10

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

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

3279

2023.07.26

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

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2858

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

1508

2023.08.01

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
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