信号量例子是从nginx项目中分离出来,并加入了gflag第三方库。
#include <iostream>
#include <string.h>
#include <gflags/gflags.h>
#include <signal.h>
#include <unistd.h>
using namespace std;
using namespace google;
#define ngx_signal_helper(n) SIG##n
#define ngx_signal_value(n) ngx_signal_helper(n)
#define ngx_value_helper(n) #n
#define ngx_value(n) ngx_value_helper(n)
#define NGX_SHUTDOWN_SIGNAL QUIT
#define NGX_TERMINATE_SIGNAL TERM
#define NGX_NOACCEPT_SIGNAL WINCH
#define NGX_RECONFIGURE_SIGNAL HUP
#define NGX_REOPEN_SIGNAL USR1
#define NGX_CHANGEBIN_SIGNAL USR2
#define ngx_errno errno
#define NGX_OK 0
#define NGX_ERROR -1
typedef intptr_t ngx_int_t;
typedef int ngx_err_t;
static void
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext);
typedef struct {
int signo;
char *signame;
char *name;
void(*handler)(int signo, siginfo_t *siginfo, void *ucontext);
} ngx_signal_t;
ngx_signal_t signals[] = {
{ ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
"SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
"reload",
ngx_signal_handler },
{ ngx_signal_value(NGX_REOPEN_SIGNAL),
"SIG" ngx_value(NGX_REOPEN_SIGNAL),
"reopen",
ngx_signal_handler },
{ ngx_signal_value(NGX_NOACCEPT_SIGNAL),
"SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
"",
ngx_signal_handler },
{ ngx_signal_value(NGX_TERMINATE_SIGNAL),
"SIG" ngx_value(NGX_TERMINATE_SIGNAL),
"stop",
ngx_signal_handler },
{ ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
"SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
"quit",
ngx_signal_handler },
{ ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
"SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
"",
ngx_signal_handler },
{ SIGALRM, "SIGALRM", "", ngx_signal_handler },
{ SIGINT, "SIGINT", "", ngx_signal_handler },
{ SIGIO, "SIGIO", "", ngx_signal_handler },
{ SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
{ SIGSYS, "SIGSYS, SIG_IGN", "", NULL },
{ SIGPIPE, "SIGPIPE, SIG_IGN", "", NULL },
{ 0, NULL, "", NULL }
};
static bool ValidatePort(const char *flagname, int32_t val)
{
if (val > 0 && val < 32768)
return true;
return false;
}
DEFINE_string(s, "", "reload pragam");
DEFINE_int32(pid, 0, "process id");
ngx_int_t
ngx_init_signals();
static bool brun = true;
int main(int argc, char **argv)
{
ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_s.compare("reload") == 0)
{
kill(FLAGS_pid, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
}
else{
ngx_init_signals();
do
{
sleep(1);
} while (brun);
}
return 0;
}
ngx_int_t
ngx_init_signals()
{
ngx_signal_t *sig;
struct sigaction sa;
for (sig = signals; sig->signo != 0; sig++) {
memset(&sa,0, sizeof(struct sigaction));
if (sig->handler) {
sa.sa_sigaction = sig->handler;
sa.sa_flags = SA_SIGINFO;
}
else {
sa.sa_handler = SIG_IGN;
}
sigemptyset(&sa.sa_mask);
if (sigaction(sig->signo, &sa, NULL) == -1) {
return NGX_ERROR;
}
}
return NGX_OK;
}
static void
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext)
{
char *action;
ngx_int_t ignore;
ngx_err_t err;
ngx_signal_t *sig;
ignore = 0;
err = ngx_errno;
for (sig = signals; sig->signo != 0; sig++) {
if (sig->signo == signo) {
break;
}
}
action = "";
switch (signo) {
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
break;
case ngx_signal_value(NGX_TERMINATE_SIGNAL):
case SIGINT:
break;
case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
break;
case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
printf("rev signal hup\n");
brun = false;
break;
case ngx_signal_value(NGX_REOPEN_SIGNAL):
break;
case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
break;
case SIGALRM:
break;
case SIGIO:
break;
case SIGCHLD:
break;
}
}