c++ - 使用 Boost.ASIO 读取时标准输入管道未关闭

标签 c++ asynchronous boost boost-asio

我正在使用 Boost.ASIO 读取标准输入,但是当我通过管道输入它时,我希望管道在输入完全消耗时关闭。 IE。我在命令行执行此操作:

cat somefile.txt | myprog

而且我希望 myprog 会看到文件关闭。相反,它会永远等待。

代码如下所示:

boost::asio::posix::stream_descriptor as_stdin(ios);
{
    boost::system::error_code error;
    as_stdin.assign(dup(STDIN_FILENO), error);
    if ( error ) {
        exit(2);
    }
}
auto proc = [&as_stdinr](auto yield) {
        boost::asio::streambuf buffer;
        while ( as_stdin.is_open() ) {
            auto bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield);
            if ( bytes ) {
                buffer.commit(bytes);
                std::istream in(&buffer);
                std::string line;
                std::getline(in, line);
                std::cerr << line << std::endl;
            } else {
                std::cerr << "No bytes read" << std::endl;
            }
        }
        std::cerr << "Done" << std::endl;
    };
boost::asio::spawn(ios, proc);

所有文件内容都被正确回显,因此从管道读取工作正常,但“未读取字节”或“完成”消息都没有被打印出来。我已经尝试过使用和不使用 dup 系统调用。

我是不是误解了管道的工作原理,还是我做错了什么或遗漏了什么?

我认为这归结为“使用协程时如何检测 EOF?”

最佳答案

您可以从 async_read_until 捕获异常

size_t bytes = 0;
bool eof = false;
try {
    bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield);
} catch(std::exception const& e) {
    std::cerr << "Exception: " << e.what() << "\n";
    bytes = 0;
    eof = true;
}
// ...
if (eof) break;

或者使用错误代码:

boost::system::error_code ec;
auto bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield[ec]);
// ...
if (ec) {
    std::cerr << "Error: " << ec.message() << "\n";
    break;
}

两种情况下的输出非常相似

Exception: End of file
No bytes read
Done

或者

No bytes read
Error: End of file
Done

限制

常规文件不能与 POSIX stream_descriptor 一起使用,参见 https://stackoverflow.com/a/23631715/85371

关于c++ - 使用 Boost.ASIO 读取时标准输入管道未关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40571429/

相关文章:

c++ - C++代码错误

c++ - 如何在 C/C++ 中释放数组

python - 使用扭曲将文件读取到标准输出

c++ - 使文件不适用于 boost

c++ - 链表C++中的内存管理错误

node.js - Node.js 中子进程和异步编程的概念在某种程度上是相同的吗?

node.js - 等待模块导入异步初始化的最佳方法?

c++ - C++中boost vector 的子类

c++ - 使用 BOOST_STRONG_TYPEDEF 来区分 arg 类型但导致段错误

c++ - 现在我无法让分子输出任何数字。当我这样做时,我得到 0/任何分母。我错过了什么?