Boost.Process:捕获的stdout被缓冲直到大小为X.

时间:2016-11-09 19:41:45

标签: c++ boost process

我正在使用boost.process来启动另一个进程。 我想抓住标准输出并自己打印。 问题是,输出只打印在块中或停止子进程时。 测试子进程是一个python脚本,每秒调用echo "test" 20次。

void ExternalAppLauncher::setup()
{
    boost::process::pipe stdout_p = boost::process::create_pipe();
    boost::process::pipe stderr_p = boost::process::create_pipe();

    {
        file_descriptor_sink stdout_sink(stdout_p.sink, close_handle);
        file_descriptor_sink stderr_sink(stderr_p.sink, close_handle);
        file_descriptor_source stdout_source(stdout_p.source,  close_handle);
        file_descriptor_source stderr_source(stderr_p.source,  close_handle);

        out_stream.open(stdout_source);
        err_stream.open(stderr_source);

        childProcess.reset(new child(execute(
                                         set_args(args),
                                         bind_stdout(stdout_sink),
                                         bind_stderr(stderr_sink),
                                         inherit_env(),
                                         // Guarantees that the child process gets killed, even when this process recieves SIGKILL(9) instead of SIGINT(2)
                                         on_exec_setup([](executor&)
        {
            ::prctl(PR_SET_PDEATHSIG, SIGKILL);
        })
                                     )));
    }
}

// runs in another thread
void ExternalAppLauncher::run()
{
    std::string s;
    while (std::getline(err_stream, s))
    {
        std::cout << s;
    }
}

这只会每隔10秒打印一次输出,可能是因为缓冲区需要先填充才能被删除? 当我不打电话bind_stdout()时,输出会立即显示在控制台上。 什么可以解决这个问题?

谢谢!

1 个答案:

答案 0 :(得分:1)

正如我在线程How to capture standard out and print to both the console and a file during process runtime (C++/Boost.Process)中发现的那样,我运行的python脚本是罪魁祸首。 使用export PYTHONUNBUFFERED=1取消激活python脚本的缓冲解决了它。 可以使用set_env:

将env var传递给应用程序
    childProcess.reset(new child(execute(
                                     set_args(args),
                                     start_in_dir(workingDir),
                                     bind_stdout(stdout_sink),
                                     bind_stderr(stderr_sink),
                                     inherit_env(),
                                     set_env(std::vector<std::string> {"PYTHONUNBUFFERED=1"}))));