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

c++如何读取并处理实时生成的管道数据流【实战】

风萱君_2184

风萱君_2184

发布时间:2026-04-08 21:36:03

|

1025人浏览过

|

来源于php中文网

原创

std::ifstream 直接读命名管道会卡死,因其构造时以阻塞模式打开 FIFO,需写端就绪;应改用 open() 配 O_NONBLOCK + fdopen() 绑定 std::filebuf,或直接 read() + 手动缓冲解析。

c++如何读取并处理实时生成的管道数据流【实战】

用 std::ifstream 直接读管道会卡死?原因和绕过方式

Linux 下通过 mkfifo 创建的命名管道(FIFO),不能像普通文件一样用 std::ifstream 构造时直接打开——它会阻塞直到有写端打开,且默认以只读阻塞模式打开,一旦写端关闭,read() 返回 0,std::ifstream::eof() 立即为 true,后续 >> 或 getline() 不再触发读取。这不是 bug,是 POSIX 管道语义决定的。

实操建议:

  • 用 open() 系统调用配合 O_RDONLY | O_NONBLOCK 打开 FIFO,避免初始阻塞;若需等待写端,去掉 O_NONBLOCK,但必须确保写端一定会启动,否则程序挂起
  • 拿到 fd 后,用 fdopen() 包装成 FILE*,再用 std::istream 的 std::filebuf 绑定(而非直接用 std::ifstream)
  • 更稳妥的做法是跳过 iostream,直接用 read() + std::vector<char></char> 缓冲区做流式解析,尤其当数据无固定分隔、或含二进制内容时

处理带换行的文本流:为什么 std::getline() 可能漏数据

如果写端用 echo "a" > mypipe 循环发数据,每条末尾带 \n,看起来适合 std::getline()。但问题在于:std::getline() 内部依赖 streambuf::sgetn(),而底层 fd 若处于阻塞模式,一次 read() 可能只返回部分字节(比如只读到半个 UTF-8 字符或不完整 JSON 字段),std::getline() 就会把这部分暂存进内部缓冲,等下次调用才拼合——导致你看到“延迟一行”或“首字符丢失”。

推荐做法:

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

C++14
C++14

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

下载
  • 自己管理缓冲区:每次 read(fd, buf, sizeof(buf)-1),手动查找 \n 边界,把完整行切出来处理
  • 若确定每条消息以 \n 结尾且不含嵌套换行,可用 std::string line; while (std::getline(std::cin, line)) { /* 处理 */ } ——但前提是标准输入已重定向到管道(./a.out ),此时 shell 已完成 fd 绑定,且 <code>std::cin 的缓冲行为更可控
  • 避免在循环里反复构造 std::string,对高频流用 std::string_view 指向缓冲区子串

如何安全应对写端意外退出?检查 read() 返回值比 eof() 更可靠

管道写端关闭时,read() 返回 0;出错时返回 -1 并设置 errno(如 EAGAIN、EINTR)。但 std::ifstream::eof() 只在尝试读取失败后才置位,且一旦置位不会自动清除——哪怕写端重新打开,流状态也不会恢复。

关键判断逻辑必须基于系统调用返回值:

  • ssize_t n = read(fd, buf, sizeof(buf)-1);
  • 若 n > 0:正常读到数据,处理 buf[0..n-1]
  • 若 n == 0:写端关闭,可选择退出循环或等待重连(需额外机制)
  • 若 n == -1:
    • errno == EAGAIN || errno == EWOULDBLOCK:非阻塞模式下暂时无数据,继续轮询或 poll()
    • errno == EINTR:被信号中断,应重试 read()
    • 其他错误(如 EBADF):需记录日志并终止

性能瓶颈常在 std::cout 和频繁 new,别让日志拖垮实时性

调试时习惯加 std::cout ,但在千行/秒级管道流中,<code>std::cout 默认全缓冲,且格式化开销大;若还用了 std::endl,每次强制 flush,性能断崖下跌。

轻量级替代方案:

  • 用 write(STDOUT_FILENO, ...) 直接刷裸字节,绕过 iostream 缓冲和 locale 处理
  • 日志聚合:把多条消息攒成一个 std::string 再一次性输出,减少系统调用次数
  • 完全禁用调试输出:编译时用宏控制,如 #ifdef DEBUG_LOG write(...); #endif,避免运行时分支判断
  • 若必须用 C++ 流,至少设为无缓冲:std::cout.sync_with_stdio(false); std::cin.tie(nullptr);,并在关键路径避免 std::endl

真正难的不是读通管道,而是写端发送节奏不可控、消息边界模糊、或需要跨进程同步状态——这些得靠协议层设计,而不是靠换一个 std::getline() 调用解决。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

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

热门AI工具

更多
二狗PPT
二狗PPT Hot

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

WorkBuddy

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

Laper
Laper Hot

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

DeepSeek

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

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

讯飞智作

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

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

PixTV
PixTV Hot

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

豆包大模型

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

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2275

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3702

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1236

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

4279

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7239

2023.08.02

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

4450

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

3733

2023.06.29

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

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

精品课程

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