如何使用C ++ Future读取标准输入而不会阻塞?

问题描述 投票:0回答:1

测试程序StdoutWriter在1秒内将一些文本({“ id”:0,“ cmd”:1}写入stdout,然后在5秒后再次写入,然后等待10秒后退出。我已经单独运行了该程序,并验证了时间和输出是否正确。

另一个测试程序StdinReader(下面给出的代码),使用将来的程序会读取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

这是我从https://gist.github.com/vmrob/ff20420a20c59b5a98a1获得的StdinReader的代码:>

#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在1秒内将一些文本({“ id”:0,“ cmd”:1})写到stdout,然后在5秒后再次写入,然后等待10秒然后退出。我已经单独运行了该程序并验证了...

c++ stdin future nonblocking
1个回答
1
投票

您的StdoutWriter程序可能实际上并不像您认为的那样向stdout写入。如果在编写后显式刷新输出流,则您的StdinReader可能会按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.