用c/c++编的程序, 有时会因为某种错误而终止, 如果我们希望终止了也能及时重启. 那么可以考虑monitor/worker模式.
父进程作为monitor, 子进程作真实的工作, 每次子进程终止的时候, monitor通过wait得知, 然后重新fork一个工作子进程, 当monitor被信号杀死的时候, 则杀掉子进程, 唯一的问题是当monitor 被SIGKILL杀死的时候, 无法添加信号回调函数, 也就无法杀掉子进程.
父进程作为monitor, 子进程作真实的工作, 每次子进程终止的时候, monitor通过wait得知, 然后重新fork一个工作子进程, 当monitor被信号杀死的时候, 则杀掉子进程, 唯一的问题是当monitor 被SIGKILL杀死的时候, 无法添加信号回调函数, 也就无法杀掉子进程.
/**
* Monitor to respawn a working process
*/
bool terminating = false;
pid_t child_pid = 0;
// This function will be called on calling exit() or return of main()
static void on_monitor_exit()
{
if(child_pid != 0) {
terminating = true;
kill(child_pid, SIGINT);
}
}
static void stop_monitor(int v) {
if(child_pid != 0) {
// Send sigint to child worker
terminating = true;
kill(child_pid, SIGINT);
} else {
exit(128+v); // 128 + signal is the default exit status on signal
}
}
static void reload(int v) {
// doesnot terminate monitor, restart child instead
if(child_pid != 0) {
kill(child_pid, SIGINT);
} else {
exit(128+v); // 128 + signal is the default exit status on signal
}
}
int main(int argc, char ** argv) {
static bool monitor_initialized = false;
while(!terminating) {
child_pid = fork();
if(child_pid == 0) {
// In child process, do the actual work
return child_run(argc, argv);
} else {
if(!monitor_initialized) {
signal(SIGINT, stop_monitor);
signal(SIGTERM, stop_monitor);
signal(SIGHUP, reload);
atexit(on_monitor_exit);
monitor_initialized = true;
}
// Wait for child return
int child_status;
pid_t pid = wait(&child_status);
if(pid != child_pid) {
break;
}
}
}
// Monitor stops
}