Linux 启动和观看另一个进程的最佳实践
Linux best practice to start and watch another process
在我的流程中,我需要 start/restart 另一个流程。
目前我使用一个堆栈大小很小的线程和以下代码:
void startAndMonitorA()
{
while(true)
{
system("myProcess");
LOG("myProcess crashed");
usleep(1000 * 1000);
}
}
我觉得这不是最佳做法。我不知道 std::system()
调用正在阻塞或浪费的资源。我使用的是嵌入式 Linux - 所以总的来说,我尽量关心资源。
一个有问题的部分是立即重新启动:如果子进程无法启动,将导致 100% CPU 使用率。它可能是子进程中的暂时性错误(例如,无法连接到服务器)。在尝试重新启动之前添加至少一秒钟的暂停可能是个好主意。
system
调用对 Linux 的作用是:
- 设置要忽略的信号
SIGINT
和 SIGQUIT
。
- 屏蔽信号
SIGCHLD
。
fork()
- 子进程调用
exec()
shell,将命令行传递给 shell。
- 父进程调用
waitpid()
阻塞线程直到子进程终止。
- 父进程恢复其信号配置。
如果您要重新实现 system
的功能,您可能会省略第 5 步(以及第 1、2 和 6 步)以避免阻塞线程并依赖 SIGCHLD
当子进程终止并需要重新启动时收到通知。
换句话说,最低限度是为 SIGCHLD
设置一个信号处理程序并调用 fork
和 exec
。
所示代码适用于大多数情况。如果您真的关心资源使用情况,您应该意识到您正在为您正在监视的每个进程启动(并保持)一个线程。如果您的程序无论如何都有一个事件循环,那么可以通过一些额外的努力(并增加复杂性)来避免这种事情。
实现这一点需要以下内容:
- 而不是调用
system()
,而是使用 fork()
和 exec()
来启动外部程序。将其 PID 存储在全局 table. 中
- 设置一个
SIGCHLD
处理程序来通知事件循环 child 的退出,例如通过向事件循环监视的管道写入一个字节。
- 当 child 退出时,运行
waitpid
与 WNOHANG
标志在循环中 运行s 只要有 child仁有所得。 waitpid()
将 return 退出的 child 的 PID,以便您知道从 table 中删除其 PID,并安排重新启动它的超时。
在我的流程中,我需要 start/restart 另一个流程。 目前我使用一个堆栈大小很小的线程和以下代码:
void startAndMonitorA()
{
while(true)
{
system("myProcess");
LOG("myProcess crashed");
usleep(1000 * 1000);
}
}
我觉得这不是最佳做法。我不知道 std::system()
调用正在阻塞或浪费的资源。我使用的是嵌入式 Linux - 所以总的来说,我尽量关心资源。
一个有问题的部分是立即重新启动:如果子进程无法启动,将导致 100% CPU 使用率。它可能是子进程中的暂时性错误(例如,无法连接到服务器)。在尝试重新启动之前添加至少一秒钟的暂停可能是个好主意。
system
调用对 Linux 的作用是:
- 设置要忽略的信号
SIGINT
和SIGQUIT
。 - 屏蔽信号
SIGCHLD
。 fork()
- 子进程调用
exec()
shell,将命令行传递给 shell。 - 父进程调用
waitpid()
阻塞线程直到子进程终止。 - 父进程恢复其信号配置。
如果您要重新实现 system
的功能,您可能会省略第 5 步(以及第 1、2 和 6 步)以避免阻塞线程并依赖 SIGCHLD
当子进程终止并需要重新启动时收到通知。
换句话说,最低限度是为 SIGCHLD
设置一个信号处理程序并调用 fork
和 exec
。
所示代码适用于大多数情况。如果您真的关心资源使用情况,您应该意识到您正在为您正在监视的每个进程启动(并保持)一个线程。如果您的程序无论如何都有一个事件循环,那么可以通过一些额外的努力(并增加复杂性)来避免这种事情。
实现这一点需要以下内容:
- 而不是调用
system()
,而是使用fork()
和exec()
来启动外部程序。将其 PID 存储在全局 table. 中
- 设置一个
SIGCHLD
处理程序来通知事件循环 child 的退出,例如通过向事件循环监视的管道写入一个字节。 - 当 child 退出时,运行
waitpid
与WNOHANG
标志在循环中 运行s 只要有 child仁有所得。waitpid()
将 return 退出的 child 的 PID,以便您知道从 table 中删除其 PID,并安排重新启动它的超时。