c++ - 在 std::cin 上累积积压会导致它丢失数据
问题描述
我有一个外部二进制文件,它向标准输出产生无限的二进制数据流(~10 MiB/s),我正在尝试编写一个 C++ 程序来使用它。我的消费者程序有一个不寻常的模式:它首先从流中读取少量数据(~32KiB),处理大约一分钟,然后以更快的速度(> 50 MiB/s)再次开始消费数据.
我正在调用该程序,如下所示:$ my_producer | my_consumer
.
因为消费者最初比消费者慢得多,所以我预计管道会积压约60s * 10 MiB/s = 600 MiB
. 然而,在一分钟的初始延迟之后,我的消费者开始以大约 10MiB/s 的速度消费数据,这意味着在一分钟间隔内产生的数据丢失了;为什么?
消费者的相关代码是这样的:
std::vector<char> StreamSource::Read(std::size_t size) {
auto data = std::vector<char>(size);
stream_.read(data.data(), size);
data.resize(stream_.gcount());
assert(stream_.good() || stream_.eof());
return data;
}
std::istream& stream_; // Initialized to std::cin
有趣的是,写入文件然后将该文件传递给消费者可以按预期工作!
$ my_producer > ~/Desktop/data
$ cat ~/Desktop/data | my_consumer
我进行了一系列测试,以确保我的制片人不会受到责备;以下失败,因为生产者检测到“短写”:
$ my_producer | throttle -M1 > ~/Desktop/data
我正在寻找有关如何解释丢失数据的建议。如果它是相关的,我在 MacOS 上运行。
谢谢!
解决方案
我很确定没有操作系统允许管道建立到 600mb,当管道满时写入端将阻塞。如果你想允许建立这么多数据,你需要在你的应用程序中有一个线程cin
连续读取并缓冲数据,然后你的应用程序可以从该缓冲区读取,而不是从cin
.
根据https://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer,管道通常最大为 64K。
推荐阅读
- spring-boot - 为什么必须在 AbstractMongoClientConfiguration 中指定数据库名称?
- javascript - 待办事项列表删除所有功能
- javascript - 正则表达式在多个方括号内返回内容
- php - 如何通过 FORM 将数据插入 MYSQL
- javascript - 如何根据值更改元素的颜色
- postgresql - Aurora Postgresql 中的副本和数据库实例有什么区别?
- python - 我们应该使用多少次福特-富克森?
- javascript - 搜索表格单元格
- javascript - 三元条件找expmod?
- python - 如何在Django中将图像从一个表移动到另一个表