1、问题描述
有时候服务端程序会偶现异常停止,这个时候除了要查找程序的bug外,还有拉起程序以继续提供服务。目前为了方便,我们直接用shell脚本去监控服务进程,这种方法比较简单,不再赘述。这里描述另一种方法:服务进程分离为主监控进程和子工作进程,主进程只负责监控子进程(停止、拉起子进程等),子进程负责对外提供服务。
监控子进程的程序,个人认为重点如下:
- 子进程收到终止信号后,完成自身善后工作,然后直接调用exit()终止。
- 父进程收到子进程终止的信号后,先调用waitpid()回收子进程的资源,避免僵尸进程,再拉起新的子进程。
- 父进程收到终止信号后,首先调用kill()通知子进程终止,然后调用waitpid()等待子进程终止并回收子进程的资源,最后父进程调用exit()终止。
2、程序源码
下面直接贴上代码(直接g++编译即可):
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
static sig_atomic_t reap;
static sig_atomic_t terminate;
static pid_t master_pid;
static pid_t worker_pid;
static const char* szfilename = "/tmp/my_test_daemon.txt";
void signal_handler(int signo);
void worker(long i);
void init_signals();
void start_worker_processes();
bool start_daemon();
typedef struct {
int signo; //需要处理的信号
void (*handler)(int signo); //收到signo信号后就会回调handler方法
} signal_t;
//指定各种信号的处理函数
signal_t signals[] = {
{SIGHUP, signal_handler},
{SIGQUIT, signal_handler},
{SIGTERM, signal_handler},
{SIGALRM, signal_handler},
{SIGINT, signal_handler},
{SIGIO, signal_handler},
{SIGCHLD, signal_handler},
{SIGSYS, SIG_IGN},
{SIGPIPE, SIG_IGN},
{