c++ - 如何在 Boost.Process 0.5 中将程序终止与流结束绑定(bind)?

标签 c++ boost process boost-iostreams

在这个 Boost.Process 0.5 ( http://www.highscore.de/boost/process0.5/index.html ) 的简单示例中,程序 (ls) 的输出正在提供一个流。流工作正常但与预期相反,流在程序完成后不会变为无效(例如流结束)(类似于以前版本的 Boost.Process,例如 http://www.highscore.de/boost/process/index.html )

为了使流(示例中的)在子程序退出后自动失效,我缺少什么?

也许这是我必须在 file_descriptor 的 Boost.Streams stream 中设置的一个选项?

#include <boost/process.hpp> // version 0.5 from http://www.highscore.de/boost/process0.5/process.zip
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;
int main(){
    boost::process::pipe p = create_pipe();
    file_descriptor_sink sink(p.sink, close_handle);
    child c = execute(run_exe("/usr/bin/ls"), bind_stdout(sink));
    file_descriptor_source source(p.source,  close_handle);
    stream<file_descriptor_source> is(source);
    std::string s;
    while(std::getline(is, s)){
        std::cout << "read: " << s << std::endl;
    }
    std::clog << "end" << std::endl; // never reach
}

最佳答案


2020 年更新:Boost.Process 现在是 Boost 的一部分 https://www.boost.org/doc/libs/1_74_0/doc/html/process.html这个答案可能已经完全过时了。它仅适用于实验版本“0.5”http://www.highscore.de/boost/process0.5/index.html .


我与库的作者 Boris Schaeling 进行了私有(private)(实际上是通过 Nabble)通信。在排除了几种可能性之后,比如 posix/boost.iostreams 中的错误,他给了我对有效代码的轻微修改。基本上,我可以推断出 file_descriptor sink 必须超出范围(已销毁)才能使流返回 EOF。工作代码只是为 sink 添加了一个特定的范围(在最后列出)。我认为这很容易将所有内容封装在 pistream 类中。 (我列表中的下一步将是允许输出到进程。)

适用于 Boost 1.48 (Fedora 17)。

#include <boost/process.hpp> // version 0.5
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>

using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;

int main() {
    pipe p = create_pipe();
    {
        // note the scope for sink
        file_descriptor_sink sink(p.sink, close_handle);
        /*  child c = */ // not necessary to hold a child object, it seems.
        execute(run_exe("/usr/bin/ls"), bind_stdout(sink));
    }   // note the scope for sink

    file_descriptor_source source(p.source,  close_handle);
    stream<file_descriptor_source> is(source);
    std::string s;
    while(std::getline(is, s)) {
        std::cout << "read: " << s << std::endl;
    }
    std::clog << "end" << std::endl; // never reach
}

使用 c(lang)++ -lboost_system -lboost_iostreams 编译

编辑:这似乎也有效,避免了人为范围,但可能会造成混淆,因为接收器必须是临时的:

    ...
    pipe p = create_pipe();
    execute(run_exe("/usr/bin/ls"), bind_stdout(        
        file_descriptor_sink(p.sink, close_handle)
    ));
    file_descriptor_source source(p.source,  close_handle);
    ...

关于c++ - 如何在 Boost.Process 0.5 中将程序终止与流结束绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12329065/

相关文章:

c++ - 检查失败 : 1 == NumElements() (1 vs. 1792)在 Tensorflow C++ 中必须有一个元素张量

c++ - 具有 2 种不同类型的对象的重载运算符声明

c++ - 使用 boost 条件变量

c++ - boost CRC 16 位

c++ - Boost 预处理器中的迭代限制

c# - 从 C# 运行时命令行进程不工作

python - 未运行、未重用、已死或僵尸的 psutil 进程

c++ - 如何从 vector <char>中提取不同数据类型的子 vector ?

c++ - 空嵌套元组错误

bash - Shell 脚本无法杀死进程