标签:live handle set eof ddr stat with psi temp
目录
srand(time(NULL)^getpid());
struct timeval tv;
gettimeofday(&tv,NULL);
dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
在main()函数中,通过配置文件判断是否以守护进程模式运行。
if (server.daemonize) daemonize(); // 守护进程
if (server.daemonize) createPidFile(); // 记录pid的文件
// 将程序以守护进程方式运行
void daemonize(void) {
int fd;
if (fork() != 0) exit(0); /* parent exits */
setsid(); /* create a new session */
/* Every output goes to /dev/null. If Redis is daemonized but
* the ‘logfile‘ is set to ‘stdout‘ in the configuration file
* it will not log at all. */
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > STDERR_FILENO) close(fd);
}
}
// 保存进程ID到文件
void createPidFile(void) {
/* Try to write the pid file in a best-effort way. */
FILE *fp = fopen(server.pidfile,"w");
if (fp) {
fprintf(fp,"%d\n",(int)getpid());
fclose(fp);
}
}
// 初始化服务器函数
void initServer(void) {
// 忽视信号: SIGHUP, SIGPIPE
signal(SIGHUP, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
// 设置SIGTERM, SIGINT 信号处理函数
setupSignalHandlers();
// 设置信号处理函数,当SIGTERN, SIGINT时,退出程序
void setupSignalHandlers(void) {
struct sigaction act;
/* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
* Otherwise, sa_handler is used. */
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = sigShutdownHandler;
sigaction(SIGTERM, &act, NULL);
sigaction(SIGINT, &act, NULL);
#ifdef HAVE_BACKTRACE
sigemptyset(&act.sa_mask);
act.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
act.sa_sigaction = sigsegvHandler;
sigaction(SIGSEGV, &act, NULL);
sigaction(SIGBUS, &act, NULL);
sigaction(SIGFPE, &act, NULL);
sigaction(SIGILL, &act, NULL);
#endif
return;
}
// 信号处理函数,ctrl+c 会产生 SIGINT信号,连续两次,会退出程序。
static void sigShutdownHandler(int sig) {
char *msg;
switch (sig) {
case SIGINT:
msg = "Received SIGINT scheduling shutdown...";
break;
case SIGTERM:
msg = "Received SIGTERM scheduling shutdown...";
break;
default:
msg = "Received shutdown signal, scheduling shutdown...";
};
/* SIGINT is often delivered via Ctrl+C in an interactive session.
* If we receive the signal the second time, we interpret this as
* the user really wanting to quit ASAP without waiting to persist
* on disk. */
if (server.shutdown_asap && sig == SIGINT) {
redisLogFromHandler(REDIS_WARNING, "You insist... exiting now.");
rdbRemoveTempFile(getpid());
exit(1); /* Exit with an error since this was not a clean shutdown. */
} else if (server.loading) {
exit(0);
}
redisLogFromHandler(REDIS_WARNING, msg);
// 在接收到SIGTERM/SIGINT信号后,在信号处理函数中将server.shutdown_asap置为1;
// 当下次运行serverCron函数时,会检查该值,然后安全退出程序。
server.shutdown_asap = 1;
}
/* Logs the stack trace using the backtrace() call. This function is designed
* to be called from signal handlers safely. */
void logStackTrace(ucontext_t *uc) {
void *trace[100];
int trace_size = 0, fd;
int log_to_stdout = server.logfile[0] == ‘\0‘;
/* Open the log file in append mode. */
fd = log_to_stdout ?
STDOUT_FILENO :
open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644);
if (fd == -1) return;
/* Generate the stack trace */
trace_size = backtrace(trace, 100);
/* overwrite sigaction with caller‘s address */
if (getMcontextEip(uc) != NULL)
trace[1] = getMcontextEip(uc);
/* Write symbols to log file */
backtrace_symbols_fd(trace, trace_size, fd);
/* Cleanup */
if (!log_to_stdout) close(fd);
}
标签:live handle set eof ddr stat with psi temp
原文地址:https://www.cnblogs.com/walkinginthesun/p/9777221.html