C++ 使用Boost监视子进程的创建
我正在我的程序中创建一个进程(比如进程X),该进程可以创建子进程,它们也可以创建子进程,并且我很难确定进程树何时完成(=所有子进程都已退出) 我还没有找到任何直接的Boost方法来做到这一点 我的(非防弹)解决方案是维护一个受监控进程的列表,从列表中的进程X开始,定期监控系统中的进程,当检测到一个进程的父id在列表中时,也将该进程id添加到列表中。一旦我进入了一个监控周期,该周期指示列表中的所有流程都已完成,那么流程树就完成了 这种方法的两个主要问题是:C++ 使用Boost监视子进程的创建,c++,boost,boost-process,C++,Boost,Boost Process,我正在我的程序中创建一个进程(比如进程X),该进程可以创建子进程,它们也可以创建子进程,并且我很难确定进程树何时完成(=所有子进程都已退出) 我还没有找到任何直接的Boost方法来做到这一点 我的(非防弹)解决方案是维护一个受监控进程的列表,从列表中的进程X开始,定期监控系统中的进程,当检测到一个进程的父id在列表中时,也将该进程id添加到列表中。一旦我进入了一个监控周期,该周期指示列表中的所有流程都已完成,那么流程树就完成了 这种方法的两个主要问题是: m_process = ps::exec
m_process = ps::execute(
boost::process::initializers::set_cmd_line(...),
boost::process::initializers::bind_stdout(sink), // route stdout to a sink/pipe
boost::process::initializers::set_env(...),
boost::process::initializers::start_in_dir(...),
boost::process::initializers::throw_on_error());
boost::system::error_code ec;
int tmp = ps::wait_for_exit(m_process,timeout,ec);
一个过程可能“滑出”——考虑下面的流程:
- 监控周期已结束,列表为[X]
- 进程X创建进程Y,进程Y创建Z并终止
- 监控循环已开始-它不会检测到进程Y,因为它
已完成,它将不会检测到进程Z,因为进程Y已完成 未检测到
m_process = ps::execute(
boost::process::initializers::set_cmd_line(...),
boost::process::initializers::bind_stdout(sink), // route stdout to a sink/pipe
boost::process::initializers::set_env(...),
boost::process::initializers::start_in_dir(...),
boost::process::initializers::throw_on_error());
boost::system::error_code ec;
int tmp = ps::wait_for_exit(m_process,timeout,ec);
流程X监控(简单、不充分的情况):
m_process = ps::execute(
boost::process::initializers::set_cmd_line(...),
boost::process::initializers::bind_stdout(sink), // route stdout to a sink/pipe
boost::process::initializers::set_env(...),
boost::process::initializers::start_in_dir(...),
boost::process::initializers::throw_on_error());
boost::system::error_code ec;
int tmp = ps::wait_for_exit(m_process,timeout,ec);
重要注意事项:
m_process = ps::execute(
boost::process::initializers::set_cmd_line(...),
boost::process::initializers::bind_stdout(sink), // route stdout to a sink/pipe
boost::process::initializers::set_env(...),
boost::process::initializers::start_in_dir(...),
boost::process::initializers::throw_on_error());
boost::system::error_code ec;
int tmp = ps::wait_for_exit(m_process,timeout,ec);
如果您可以更改子进程以报告它们使用某种IPC机制(stdout、消息队列、共享内存、命名管道…)创建的PID,那么您就可以开始了 您可以使用Boost Asio获得的句柄() 否则,您可能会绑定到面向调试的接口(需要提升权限),例如
- linux上的ptrace(参见此处的
)ptrace\u EVENT\u VFORK
- 窗口:
我建议如果你控制子进程,你最好使用IPC来协调工作我无法控制子进程(进程X),也不知道它将要做什么,或者它将产生什么进程。我会在这个问题上加上这个重要的注释。@Ron.B.I,正如你所看到的,我已经找到了相关的答案。因此,只有在Linux上,这才可能被证明是乏味的,除非有其他人参与了回答:在我们的例子中,孙子进程只是一个测试用例,我正在寻找一个通用的解决方案,我们谈论的是一个执行软件——能够在几种Linux风格和Windows上执行用户提供的命令行,用户可以运行一个脚本来启动一个安装,然后运行另一个安装,诸如此类,我们这里唯一知道的是树的根,我的过程从树开始。关于ptrace,我正在研究这个问题,但不幸的是,正如我所说的,我正在尝试为Windows和Linux解决这个问题。@Ron.B.I。对于windows变体,它已经解决了!如果您实际上希望限制Linux上的资源使用,那么可以使用
chroot+ulimit
;ulimit具有限制生成的子进程数量的功能,以及限制子代和子代(以及其他事物,如可创建的最大文件、打开的文件数量等)所消耗的CPU总时间。我这样做的主要目的是防止在第一个命令行完成树之前执行下一个命令行,给定获取正在生成的子进程信息的逻辑(没有资源限制),我可以轻松地监视并确定树是否已完成运行。