假设我有一个父进程产生很少的工作者(子进程)。 我想在其中一个子进程崩溃(被杀)时得到通知。
获取此通知的最佳方式是什么? 我用c或c ++编程。 我在unix上。并使用fork_and_exec
生成了hte子进程答案 0 :(得分:3)
如果您只想在子进程退出(正常或异常)时收到通知,您可以在父进程中为 SIGCHLD 信号编写处理程序。只要此进程生成的进程消失,就会执行此处理程序。
但是,在此处理程序中可以执行的操作存在严重限制。如果收到其他信号,该处理程序将立即中断。即使变量赋值也不是信号处理程序内部的安全操作 - 赋值可以使用两个或更多机器指令,并且可以通过新信号中断,使值未定义。可以安全地在信号处理程序内部分配的唯一变量是 sig_atomic_t 类型的变量(保证在一条指令中完成对此类变量的赋值)。
家长还必须" 等待" (使用等待函数)用于子进程 - 否则,子进程将在终止后变为僵尸。
这个解决方案在我的情况下已经足够了,因为我只需要减少sig_atomic_t类型的计数器变量。如果你需要做一些"严肃的"当孩子死亡时处理,需要其他解决方案。这个想法可能如下:
C ++示例可以在下面找到 - 请注意我没有使用线程等待孩子,但是不应该修改示例以使用线程。
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
int spawn(char* process_name, char** arguments){
pid_t child_id = fork();
if (child_id != 0)
return child_id;
else{
execvp(process_name, arguments);
fprintf(stderr, "An error occured while executing new process.\n");
abort();
}
}
int main(int argc, const char * argv[])
{
char* arguments[] = {
"/Path_to_Child_Exe/Child_Process",
nullptr
};
int i=0;
while (i++ < 10)
spawn((char*) "/Path_to_Child_Exe/Child_Process", arguments);
while (true){
siginfo_t exit_info;
int retVal = waitid(P_ALL, -1, &exit_info, WEXITED);
if (retVal == -1 && errno == ECHILD){
std::cout << "No more children.\n";
break;
}
std::cout << "Child with PID " << exit_info.si_pid << " terminated.\n";
sleep(1);
}
return 0;
}
同样重要的是要注意我们在while循环的每次迭代结束时调用sleep。在等待孩子的线程中也应该这样做。否则,如果我们在没有子进程的情况下不停顿地调用waitid()函数,CPU使用率将非常高(我猜是一种忙碌的等待形式)。因此,我们必须时不时地打电话给睡眠,让CPU有机会休息。