UNIX高级环境编程 第13章 守护进程

引言

守护进程:没有控制终端,长期运行在后台的进程

编程规则

void daemonize(const char* cmd) {
    /*
    * 调用umask将文件模式创建屏蔽字设置为0。
    * 由继承得来的文件模式创建屏蔽字可能会拒绝设置某些权限。
    */ 
    umask(0);
    /*
     * 调用fork,然后使父进程退出(exit)
     * 1.如果该守护进程是作为一条简单shell命令启动的,那么父进程终止使得shell认为这条命令已经执行完毕
     * 2.子进程继承了父进程的进程组ID,但具有一个新的进程ID,这就保证了子进程不是一个进程组的组长进程
     */
    pid_t pid = fork();
    if (pid < 0) {
        err_quit("fork fail.");
    } else if (pid != 0) {
        exit(0);
    }
    /*
     *调用setsid以创建一个新会话 使调用进程:
     * a. 成为新会话的首进程,
     * b. 成为一个新进程组的组长进程,
     * c. 没有控制终端。
     */
    setsid();
    struct sigaction sa;
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    if (sigaction(SIGHUP, &sa, NULL) < 0) {
        err_quit("sigaction err.");
    }
    
    /*
     * 终止当前进程,使得下面的代码的操作中无法获取终端控制
     * 因为只有会话首进程可以获取终端控制。
     * 
     * 注意: sigaction函数的作用在此体现: 当关闭会话首进程时,内核会向所有处于
     *       该会话的进程发送SIGHUP信号,该信号的默认处理函数是终止进程。
     */  
    if(pid = fork()) { 
        exit(0);      
    }                  
  
    else if(pid < 0) {
           exit(1);
    }                              
    /*
     * 将当前工作目录更改为根目录
     * 从父进程出继承过来的当前工作目录可能在一个挂载的文件系统中。
     * 因为守护进程通常在系统再引导之前是一直存在的,
     * 所以如果守护进程的当前工作目录在一个挂载的文件系统中,那么该文件系统就不能被卸载。
     * 这与挂载文件系统的原意不符。
     * 某些守护进程可能会把当前工作目录更改到某个指定位置,在那里做它们的工作.
     */
    if (chdir("/") < 0) {
        err_quit("chdir fail.");
    }
    struct rlimit rl;
    if(getrlimit(RLIMIT_NOFILE, &rl) < 0) {
        err_quit("getrlimit fail.");
    }
     /* 
      *关闭继承的文件描述符
      */  
    if (rl.rlim_max == RLIM_INFINITY) {    //RLIM_INFINITY是一个无穷量的限制       
        // TODO :why is 1024 ??  
        rl.rlim_max = 1024;  
    }
    for (i = 0; i < rl.rlim_max; i++) { 
        close(i);
    }
    int fd0, fd1, fd2;
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);
   /*
    * Initialize the log file.
    * cmd 函数名称
    */
    openlog(cmd, 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);
    }
}
    原文作者:shiyang6017
    原文地址: https://segmentfault.com/a/1190000009478818
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞