【问题标题】:Boost::process child by idBoost::process child by id
【发布时间】:2020-04-16 18:25:21
【问题描述】:

如何在 on_exit 函数中获取 child.id()?

bp::child c(args, ios, bp::on_exit([&](int e, std::error_code ec) {
            result = e;
            ios.stop();
            //need c.id();    

        }));

或者如果孩子按 id 运行,我如何检查其他功能?

        boost::process::child c(data->id); // doesn't work
        if (!c.running()) {
}

【问题讨论】:

    标签: c++ boost boost-process


    【解决方案1】:

    您可以将任何您想要的额外信息绑定到您的处理程序。例如,您可以声明您的处理程序以引用 child 实例:

    static void exit_handler(bp::child& process, int e, std::error_code ec) {
        std::cout << "Process " << process.id() << " exited with " << e << " (" << ec.message() << ")\n";
    }
    

    现在,您可以使用 std::bind 将其绑定到 on_exit 处理程序(当然您可以使用 lambda 来完成这项工作):

    p = bp::child(
            sv{"/bin/bash", "-c", command.str()},
            bp::on_exit(std::bind(exit_handler, std::ref(p), _1, _2)),
            io);
    
    // Or, using a lambda to capture the reference:
    p = bp::child(
            sv{"/bin/bash", "-c", command.str()},
            bp::on_exit([&p](int e, std::error_code ec) { exit_handler(p, e, ec); }),
            io);
    

    生成 11 个子进程的完整示例,这些子进程需要不同的时间

    Live On Coliru

    #include <boost/process.hpp>
    #include <boost/process/async.hpp>
    #include <iostream>
    #include <functional> // std::bind & placeholders
    #include <sstream>    // ostringstream
    
    namespace bp = boost::process;
    using namespace std::placeholders;
    using sv = std::vector<std::string>;
    
    static void exit_handler(bp::child& process, int e, std::error_code ec) {
        std::cout << "Process " << process.id() << " exited with " << e << " (" << ec.message() << ")\n";
    }
    
    int main() {
        boost::asio::io_context io;
        auto work = make_work_guard(io);
    
        std::list<bp::child> children;
    
        for (auto ch = 'a'; ch < 'k'; ++ch) {
            auto& p = children.emplace_back();
            std::ostringstream command;
            command << "echo 'hello from " << ch << "';";
            command << "sleep 0.$RANDOM;";
            command << "echo 'bye from " << ch << "';";
            command << "exit " << (rand()%42) << ";";
    
            p = bp::child(
                    sv{"/bin/bash", "-c", command.str()},
                    bp::on_exit(std::bind(exit_handler, std::ref(p), _1, _2)),
                    io);
        }
    
        work.reset(); // allow io to be finished
        io.run();     // wait for that
    
        std::cout << "Bye\n";
    }
    

    打印:

    hello from b
    hello from a
    hello from c
    hello from d
    hello from e
    hello from f
    hello from g
    hello from i
    hello from h
    hello from j
    bye from g
    bye from a
    bye from h
    bye from b
    bye from d
    bye from f
    bye from j
    bye from e
    bye from i
    bye from c
    Process 12044 exited with 10 (Success)
    Process 12034 exited with 1 (Success)
    Process 12047 exited with 30 (Success)
    Process 12035 exited with 4 (Success)
    Process 12038 exited with 19 (Success)
    Process 12043 exited with 31 (Success)
    Process 12050 exited with 31 (Success)
    Process 12042 exited with 29 (Success)
    Process 12049 exited with 15 (Success)
    Process 12036 exited with 9 (Success)
    Bye
    

    更新

    为了还能够查询哪个子进程仍在运行,请考虑使用map 而不是list(请注意您选择的容器的参考稳定性!)。

    这是一个演示Live On Coliru

    std::map<char, bp::child> children;
    
    for (char name = 'a'; name < 'k'; ++name) {
        std::ostringstream command;
        command << "echo 'hello from " << name << "';";
        command << "sleep " << (rand()%900 + 101)/1000.0 << ";";
        command << "echo 'bye from " << name << "';";
        command << "exit " << (rand()%42) << ";";
    
        auto& p = children[name];
        p = bp::child(
                sv{"/bin/sh", "-c", command.str()},
                bp::on_exit(std::bind(exit_handler, std::ref(p), _1, _2)),
                io);
    }
    
    work.reset(); // allow io to be finished
    
    while (io.run_one()) { // wait for that
        std::cout << "Still running: ";
        for (auto& [name, child] : children) {
            if (child.running())
                std::cout << " " << name;
        }
        std::cout << std::endl;
    }
    
    std::cout << "Bye\n";
    

    打印

    hello from a
    hello from b
    hello from c
    hello from d
    hello from e
    hello from f
    hello from g
    hello from h
    hello from i
    Still running:  a b c d e f g h i j
    Still running:  a b c d e f g h i j
    hello from j
    bye from i
    Still running:  a b c d e f g h j
    Process 30748 exited with -1
    Still running:  a b c d e f g h j
    bye from e
    Still running:  a b c d f g h j
    Still running:  a b c d f g h j
    Process 30739 exited with -1
    Still running:  a b c d f g h j
    bye from c
    Still running:  a b d f g h j
    Still running:  a b d f g h j
    Process 30735 exited with -1
    Still running:  a b d f g h j
    bye from b
    Still running:  a d f g h j
    Still running:  a d f g h j
    Process 30733 exited with -1
    Still running:  a d f g h j
    bye from h
    Still running:  a d f g j
    Still running:  a d f g j
    Process 30744 exited with -1
    Still running:  a d f g j
    bye from d
    Still running:  a f g j
    Still running:  a f g j
    Process 30737 exited with -1
    Still running:  a f g j
    bye from g
    Still running:  a f j
    Still running:  a f j
    Process 30743 exited with -1
    Still running:  a f j
    bye from f
    Still running:  a j
    Still running:  a j
    Process 30740 exited with -1
    Still running:  a j
    bye from j
    Still running:  a
    Still running:  a
    Process 30749 exited with -1
    Still running:  a
    bye from a
    Still running: 
    Still running: 
    Process 30732 exited with -1
    Still running: 
    Bye
    

    【讨论】:

    • 添加了一个更新,该更新也回答了问题的第二部分(或者如果孩子按 id 运行,我如何检查其他功能?)。当然,我现在通过一些选定的 id(“名称”)进行查找,但如果您愿意,您也可以通过 PID 来查找进程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    相关资源
    最近更新 更多