如何使用C++future在不阻塞的情况下读取stdin
How to read stdin without blocking using C++ future?
测试程序StdoutWriter在1秒内将一些文本({"id":0,"cmd":1}(写入stdout,然后在5秒后再次写入,然后等待10秒并退出。我自己运行了这个程序,并验证了时间和输出是否正确。
另一个测试程序StdinReader(下面给出的代码(使用future读取stdin并打印每一行StdinReader未按预期工作。
我从终端启动两个程序:
./StdoutWriter | ./StdinReader
我看到的问题是,在StdoutWriter退出之前,每一行的读取似乎都会被阻塞。
观察到的错误输出看起来像:
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
you wrote {"id":0,"cmd":1}
waiting...
you wrote
waiting...
you wrote
waiting...
you wrote
正确输出应为:
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
waiting...
waiting...
waiting...
waiting...
you wrote {"id":0,"cmd":1}
waiting...
waiting...
waiting...
waiting...
you wrote
waiting...
you wrote
waiting...
you wrote
这是我从StdinReader获得的代码:https://gist.github.com/vmrob/ff20420a20c59b5a98a1
#include <iostream>
#include <chrono>
#include <future>
#include <string>
std::string GetLineFromCin() {
std::string line;
std::getline(std::cin, line);
return line;
}
int main() {
auto future = std::async(std::launch::async, GetLineFromCin);
while (true) {
if (future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
auto line = future.get();
// Set a new line. Subtle race condition between the previous line
// and this. Some lines could be missed. To aleviate, you need an
// io-only thread. I'll give an example of that as well.
future = std::async(std::launch::async, GetLineFromCin);
std::cout << "you wrote " << line << std::endl;
}
std::cout << "waiting..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
您的StdoutWriter程序实际上可能并没有像您想象的那样写入stdout。如果您在写入后显式刷新输出流,那么您的StdinReader很可能会像您预期的那样工作。
为了提高性能,大多数I/O库在写入输出流时都会进行一定程度的缓冲。这意味着,当您写入输出流时,库通常只在内部保留数据,而不是直接将其写入其底层操作系统文件描述符。这避免了为每次写入都执行系统调用而付出代价。
缓冲级别通常会根据您要写入的文件/设备的类型而变化:
-
在向终端写入时,输出通常是行缓冲的。这意味着库将刷新其内部缓冲区,并在每次写入换行符时将输出写入底层文件描述符。
-
当写入管道或普通文件时,输出通常是完全缓冲的。这意味着,当缓冲区填满或您明确告诉它时,库只会将数据从其内部缓冲区刷新到底层文件描述符
相关文章:
- 有没有办法在不使用 getline() 的情况下从.csv文件中读取?
- 在没有密钥的情况下读取密文的剩余噪声预算
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 如何在不知道大小的情况下读取文本文件并存储到数组中
- 在不使用getline的情况下读取C 中的stdin
- 如何迭代在不知道其大小的情况下读取的字符串?
- 在不知道矩阵名称的情况下读取YML
- 我可以在不知道文本文件的列数的情况下读取二维数组中的文件吗?
- C++在不使用字符串流的情况下读取具有任意长度和格式的行的多行文件
- Windows:如何让子进程在不关闭输入匿名管道的情况下读取它
- 如何在不显示十六进制的情况下读取dat文件中的文本?C++
- 有没有办法在不加载的情况下读取 .so 文件的内容
- 如果我在键不存在的情况下读取地图的值,会发生什么情况?
- 如何在不按ENTER和不使用getch()或getche()的情况下读取C++中的字符
- 在不使用临时文件的情况下读取linux命令的输出
- 是否可以在没有安装 Office Excel 或其他先决条件框架的情况下读取 Qt 或 C++ Excel
- 我想在写入过程完成后从二进制文件中读取数据,也可以在没有写入过程的情况下读取数据
- 在未按enter确认的情况下读取组合
- 如何在没有换行符的情况下读取CSV记录"rn"?
- 如何在不知道一行文本有多少元素的情况下读取每个元素?(c++)