zoukankan      html  css  js  c++  java
  • twemproxy源码分析2——守护进程的创建

    twemproxy源码中关于守护进程的创建实现得比较标准,先贴出代码来,然后结合一些资料来分析和列举一些实现守护进程的常用方法,不过不得不说twemproxy的实现确实是不错的,注释都写在了代码中,直接上代码吧:

      1 static rstatus_t
      2 nc_daemonize(int dump_core)
      3 {
      4     rstatus_t status;
      5     pid_t pid, sid;
      6     int fd;
      7 
      8     /*
      9      * 先fork出一个子进程,把主进程关闭了
     10      */
     11     pid = fork();
     12     switch (pid) {
     13     case -1:
     14         log_error("fork() failed: %s", strerror(errno));
     15         return NC_ERROR;
     16 
     17     case 0:
     18         break;
     19 
     20     default:
     21         /* parent terminates */
     22         _exit(0);
     23     }
     24 
     25     /* 1st child continues and becomes the session leader */
     26     /*
     27      * 新fork出的子进程不可能是一个进程组的组长,这就避免了setsid函数调用的失败
     28      * 在调用了setsid函数后该进程就成为新的会话组长和新的进程组长
     29      * 并与原来的登录会话、进程组、控制终端脱离
     30      */
     31     sid = setsid();
     32     if (sid < 0) {
     33         log_error("setsid() failed: %s", strerror(errno));
     34         return NC_ERROR;
     35     }
     36 
     37     /*
     38      * 处理SIGCHLD信号,内核在子进程结束时不会产生僵尸进程
     39      */
     40     if (signal(SIGHUP, SIG_IGN) == SIG_ERR) {
     41         log_error("signal(SIGHUP, SIG_IGN) failed: %s", strerror(errno));
     42         return NC_ERROR;
     43     }
     44 
     45     /*
     46      * 再一次fork的原因是之前的子进程虽然已经脱离了控制终端,该子进程已经成为无终端的会话组长。
     47      * 但它可以重新申请打开一个控制终端,可以通过使进程不再成为会话组长来禁止进程重新打开控制终端
     48      */
     49     pid = fork();
     50     switch (pid) {
     51     case -1:
     52         log_error("fork() failed: %s", strerror(errno));
     53         return NC_ERROR;
     54 
     55     case 0:
     56         break;
     57 
     58     default:
     59         /* 1st child terminates */
     60         _exit(0);
     61     }
     62 
     63     /* 2nd child continues */
     64 
     65     /* change working directory */
     66     /*
     67      * 切换工作目录
     68      */
     69     if (dump_core == 0) {
     70         status = chdir("/");
     71         if (status < 0) {
     72             log_error("chdir("/") failed: %s", strerror(errno));
     73             return NC_ERROR;
     74         }
     75     }
     76 
     77     /* clear file mode creation mask */
     78     /*
     79      * 重设权限掩码
     80      * 进程从创建它的父进程那里继承了文件创建掩码,它可能修改守护进程所创建的文件的存取位。
     81      */
     82     umask(0);
     83 
     84     /* redirect stdin, stdout and stderr to "/dev/null" */
     85     /*
     86      * 重定向描述符
     87      */
     88     fd = open("/dev/null", O_RDWR);
     89     if (fd < 0) {
     90         log_error("open("/dev/null") failed: %s", strerror(errno));
     91         return NC_ERROR;
     92     }
     93 
     94     status = dup2(fd, STDIN_FILENO);
     95     if (status < 0) {
     96         log_error("dup2(%d, STDIN) failed: %s", fd, strerror(errno));
     97         close(fd);
     98         return NC_ERROR;
     99     }
    100 
    101     status = dup2(fd, STDOUT_FILENO);
    102     if (status < 0) {
    103         log_error("dup2(%d, STDOUT) failed: %s", fd, strerror(errno));
    104         close(fd);
    105         return NC_ERROR;
    106     }
    107 
    108     status = dup2(fd, STDERR_FILENO);
    109     if (status < 0) {
    110         log_error("dup2(%d, STDERR) failed: %s", fd, strerror(errno));
    111         close(fd);
    112         return NC_ERROR;
    113     }
    114 
    115     if (fd > STDERR_FILENO) {
    116         status = close(fd);
    117         if (status < 0) {
    118             log_error("close(%d) failed: %s", fd, strerror(errno));
    119             return NC_ERROR;
    120         }
    121     }
    122 
    123     return NC_OK;
    124 }

    关于各种ID,先贴上一个图,后面再解释

  • 相关阅读:
    常用的IDEA快捷键
    异步任务 & 定时任务 & 邮件任务
    Swagger
    路由钩子&异步请求axios
    vue-参数绑定及重定向
    Spring事务的传播机制
    使用mybatis的BaseTypeHandler来给敏感字段进行AES加密
    SpringBoot2.0.3.RELEASE+sharding-jdbc4.1.0+mybatis-plus3.4.1+druid1.1.22 快速搭建分库分表
    使用SpringCloudStream整合RabbitMQ
    获取汉字首字母
  • 原文地址:https://www.cnblogs.com/abc-begin/p/8137755.html
Copyright © 2011-2022 走看看