守护进程重读配置文件示例

守护进程重读配置文件示例

     重读APUE,对守护进程有了更加深刻的理解,特别是相应的编程规则应用场景对于为什么要fork两次,日志设施的用法,信号的处理方法都有了 更加清晰的认识。通常的应用场景是,守护进程在收到一个SIGHUP信号的时候重新读取配置文件,而不需要停止。下面是运行APUE书中这个实例的过程。

     首先主要代码为(reread.c):
#include "util.h"
#include <pthread.h>
#include <syslog.h>

sigset_t    mask;

extern int already_running(void);

void reread(void)
{
    /* 实际读取配置文件操作... */
}

void *thr_fn(void *arg)
{
    int err, signo;

    for (;;) {
        err = sigwait(&mask, &signo);
        if (err != 0) {
            syslog(LOG_ERR, "sigwait failed");
            exit(1);
        }   

        switch (signo) {
        case SIGHUP:
            syslog(LOG_INFO, "Re-reading configuration file");
            reread();
            break;

        case SIGTERM:
            syslog(LOG_INFO, "got SIGTERM; exiting");
            exit(0);

        default:
            syslog(LOG_INFO, "unexpected signal %d\n", signo);
        }   
    }
    return(0);
}

int
main(int argc, char *argv[])
{
    int                 err;
    pthread_t           tid;
    char                *cmd;
    struct sigaction    sa;

    if ((cmd = strrchr(argv[0], '/')) == NULL)
        cmd = argv[0];
    else
        cmd++;

    /*
     * Become a daemon.
     */
    daemonize(cmd);

    /*
     * Make sure only one copy of the daemon is running.
     */
    if (already_running()) {
        syslog(LOG_ERR, "daemon already running");
        exit(1);
    }

    /*
     * Restore SIGHUP default and block all signals.
     */
    sa.sa_handler = SIG_DFL;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        err_quit("%s: can't restore SIGHUP default");
    sigfillset(&mask);
    if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
        err_exit(err, "SIG_BLOCK error");

    /*
     * Create a thread to handle SIGHUP and SIGTERM.
     */
    err = pthread_create(&tid, NULL, thr_fn, 0);
    if (err != 0)
        err_exit(err, "can't create thread");

    /*
     * Proceed with the rest of the daemon.
     */
    /* ... */
    syslog(LOG_INFO, "hello vonzhou............");
    pause();


//  exit(0);
}


     此时守护进程reread已经在后台运行,通过ps -axj 命令可以看到,如:


     日志记录为:


     接下来通过命令 /bin/kill -s HUP 29440,给其发送一个SIGHUP信号,就会驱动它重读配置文件,日志记录为: 


完整的代码看这里GitHub。



你可能感兴趣的:(sigaction,SIGHUP,pthread_sigmask,daemonize)