Linux最佳实践启动并观察另一个进程

时间:2017-02-27 12:15:44

标签: c++ linux child-process

在我的过程中,我需要启动/重启另一个进程。 目前我使用一个小堆栈大小的线程和以下代码:

void startAndMonitorA()
{
  while(true)
  {
    system("myProcess");
    LOG("myProcess crashed");
    usleep(1000 * 1000);
  }
}

我觉得这不是最好的做法。我不知道std::system()调用阻塞或浪费的资源。我在嵌入式Linux上 - 所以一般来说我都会关心资源。

2 个答案:

答案 0 :(得分:3)

一个有问题的部分是立即重启:如果子进程无法启动,将导致100%的CPU使用率。它可能是子进程中的暂时性错误(例如,无法连接到服务器)。在尝试重新启动之前添加至少一秒的暂停可能是个好主意。

Linux上system调用的内容是:

  1. 设置要忽略的信号SIGINTSIGQUIT
  2. 阻止信号SIGCHLD
  3. fork()
  4. 子进程调用exec() shell,将命令行传递给shell。
  5. 父进程调用阻塞线程的waitpid(),直到子进程终止。
  6. 父进程恢复其信号处理。
  7. 如果您要重新实现system的功能,您可能会省略步骤5(以及步骤1,2和6)以避免阻塞线程并依赖SIGCHLD获得通知当子进程终止并需要重新启动时。

    换句话说,最低限度是设置SIGCHLD的信号处理程序并调用forkexec

答案 1 :(得分:0)

显示的代码适用于大多数情况。如果您真的关心资源使用情况,您应该知道您正在为正在监视的每个进程启动(并保留)一个线程。如果你的程序有一个事件循环,那么可以通过一些额外的努力(以及复杂性的增加)来避免这种事情。

实现这一点需要以下内容:

  • 使用system()fork()启动外部程序,而不是调用exec()。将其PID存储在全局表中。
  • 设置一个SIGCHLD处理程序,通知子事件退出的事件循环,例如:通过将一个字节写入由事件循环监视的管道。
  • 当一个孩子退出时,在一个循环中运行带有waitpid标志的WNOHANG,该循环只要有孩子收获就会运行。 waitpid()将返回退出的子节点的PID,以便您知道从表中删除其PID,并安排重新启动它的超时。