守护进程运用实例

1)守护进程可以直接在程序起始部分通过调用unistd中的daemon来将本进程设置为守护进程

2)可以用ps -axj | grep xx查看自己的守护进程启动情况

3)用kill可以杀死自己启动的守护进程

 

除上述直接调用,也可以自己编写自己想要的守护进程,下面是一个example,注意其中的fork两次,设置新会话setsid,更改目录到根目录chdir和重设文件权限掩码umask和关闭文件描述符: 

/// \brief closeAll close all FDs >= a specified value
///
/// \param fd
void closeAll(int fd){
    int fdlimit = sysconf(_SC_OPEN_MAX);

    while(fd < fdlimit ){
        close(fd++);
    }
}

/// \brief daemon detach process from user and disapper into the background
//returns -1 on failure, but you cannot do much except exit in that case
//since we may already have forked. this is based on the BSD version, so
//the caller is responsible for things like the umask, etc.
///
/// \param nochdir
/// \param noclose
///
/// \return
int daemon_own(int nochdir, int noclose){
 //   struct rlimit rl;
    struct sigaction sa;
    int fd0, fd1, fd2;

    umask(0);   /*clear file creation mask*/

    /*get maximum number of file descriptors*/
//    if(getrlimit(RLIMIT_NOFILE, &rl) < 0){
//#ifdef DEBUG
//        std::cout << "cannot get file limit" << std::endl;
//#endif
//        perror("getrlimit");
//    }

    /*Become a session leader to lose controlling TTY*/
    switch(fork()){
        case 0:  /*child*/
            break;
        case -1:
            return -1;
        default:   /*parent*/
            _exit(0);   /*exit the original process*/
    }

    if(setsid() < 0){   /*new session & new group, shouldn't fail*/
        return -1;
    }

    /*Ensure future opens won't allocate controlling TTYs*/
    sa.sa_handler = SIG_IGN;    /*ignore*/
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if(sigaction(SIGHUP, &sa, NULL) < 0){
#ifdef  DEBUG
        std::cout << "cannot ignore SIGHUP" << std::endl;
#endif
        perror("sigaction");
    }

    /*dyke out this switch if you want to acquire a control tty in
     * the future -- not normally advisable for daemons*/

    switch(fork()){
        case 0:
            break;
        case -1:
            return -1;
        default:
            _exit(0);
    }

    /*change the current working directory to the root so
     * we won't prevent file systems from being unmounted*/
    if(!nochdir)
        chdir("/");

    if(!noclose){
        closeAll(0);
        fd0 = open("/dev/null", O_RDWR);  /*#include <fcntl.h>*/
        fd1 = dup(0);
        fd2 = dup(0);
    }

    /*Initialize the log file*/
    openlog("test", LOG_CONS, LOG_DAEMON);
    if(fd0 != 0 || fd1 != 1 || fd2 != 2){
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2);
        exit(1);
    }
    return 0;
}

 

 

int main(int argc, char **argv){
    if((daemon_own(0, 0)) < 0){
#ifdef DEBUG
        cout << "daemon error from daemon(int, int)" << endl;
#endif
        perror("daemon");
        exit(2);
    }
process(); return 0; }

 

posted @ 2017-03-09 15:16  立超的专栏  阅读(582)  评论(0编辑  收藏  举报