11

Boost.Process 0.5 ( http://www.highscore.de/boost/process0.5/index.html ) のこの簡単な例では、プログラムの出力 ( ls) がストリームに供給されています。ストリームは正常に動作しますが、期待に反して、プログラムの終了後にストリームが無効になりません (ストリームの終わりなど) (Boost.Process の以前のバージョンと同様に、http: //www.highscore.de/boost など)。 /プロセス/index.html )

is子プログラムの終了後にストリーム (例では) を自動的に無効にするために何が欠けていますか?

おそらく、の Boost.Streams に設定する必要があるオプションstreamですかfile_descriptor?

#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
}
4

2 に答える 2

5

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と(実際には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);
    ...
于 2012-09-18T02:11:33.867 に答える
3

これは POSIX ライクなシステムで動作します:

#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 <boost/asio.hpp>
#include <string>

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

int main()
{
    boost::asio::io_service io_service;
    int status = 1;
    boost::asio::signal_set set(io_service, SIGCHLD);
    set.async_wait(
        [&status](const boost::system::error_code&, int) { ::wait(&status); }
    );

    boost::process::pipe p = create_pipe();
    file_descriptor_sink sink(p.sink, close_handle);
    child c = execute(run_exe("/bin/ls"), bind_stdout(sink));
    file_descriptor_source source(p.source,  close_handle);
    stream<file_descriptor_source> is(source);
    std::string s;
    while(status && std::getline(is, s))
    {
        std::cout << "read: " << s << std::endl;
    }
    std::clog << "end" << std::endl; // never reach
}

SIGCHLD を処理して非同期に設定することに注意してくださいstatushttp://www.highscore.de/boost/process0.5/boost_process/tutorial.html#boost_process.tutorial.starting_a_programから取得しました。このページには、同じことを行う Windows スタイルも示されています。

#if defined(BOOST_WINDOWS_API)
    DWORD exit_code;
    boost::asio::windows::object_handle handle(io_service, c.process_handle());
    handle.async_wait(
        [&handle, &exit_code](const boost::system::error_code&)
            { ::GetExitCodeProcess(handle.native(), &exit_code); }
    );
#endif

    io_service.run();
于 2012-09-11T18:59:15.977 に答える