Boost::按id处理子进程



如何在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()) {
}

您可以将任何需要的额外信息绑定到处理程序。例如,您可以声明处理程序引用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个子进程的完整示例,这些子进程占用不同的时间<1s完成并全部绑定到同一个处理程序:

在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 << "Byen";
}

打印:

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(要非常小心容器选择的引用稳定性!(。

这是一个演示在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 << "Byen";

打印

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

最新更新