Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Boost监视子进程的创建_C++_Boost_Boost Process - Fatal编程技术网

C++ 使用Boost监视子进程的创建

C++ 使用Boost监视子进程的创建,c++,boost,boost-process,C++,Boost,Boost Process,我正在我的程序中创建一个进程(比如进程X),该进程可以创建子进程,它们也可以创建子进程,并且我很难确定进程树何时完成(=所有子进程都已退出) 我还没有找到任何直接的Boost方法来做到这一点 我的(非防弹)解决方案是维护一个受监控进程的列表,从列表中的进程X开始,定期监控系统中的进程,当检测到一个进程的父id在列表中时,也将该进程id添加到列表中。一旦我进入了一个监控周期,该周期指示列表中的所有流程都已完成,那么流程树就完成了 这种方法的两个主要问题是: m_process = ps::exec

我正在我的程序中创建一个进程(比如进程X),该进程可以创建子进程,它们也可以创建子进程,并且我很难确定进程树何时完成(=所有子进程都已退出)

我还没有找到任何直接的Boost方法来做到这一点

我的(非防弹)解决方案是维护一个受监控进程的列表,从列表中的进程X开始,定期监控系统中的进程,当检测到一个进程的父id在列表中时,也将该进程id添加到列表中。一旦我进入了一个监控周期,该周期指示列表中的所有流程都已完成,那么流程树就完成了

这种方法的两个主要问题是:

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已完成 未检测到

  • 这种类型的监控非常耗费资源,因为它需要非常频繁地运行,以尽量减少问题1中描述的这些“失误”

  • 我的程序中使用的一些代码段:

    流程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);
    
    流程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);
    

  • 我无法控制子进程(进程X),我也不知道 它将要做什么,或者它将产生什么过程
  • 我的解决方案应该同时适用于windows和Linux(如果没有 如果可能的话,我将不得不在我的应用程序中使用特定于操作系统的代码 程序,这是(到目前为止)不可知的操作系统)

  • 如果您可以更改子进程以报告它们使用某种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总时间。我这样做的主要目的是防止在第一个命令行完成树之前执行下一个命令行,给定获取正在生成的子进程信息的逻辑(没有资源限制),我可以轻松地监视并确定树是否已完成运行。