zoukankan      html  css  js  c++  java
  • 拾遗:Unix 守护进程编写规范

    //标准库自带函数,通常以 daemon(0, 0) 方式调用
    int daemon(int nochdir, int noclose)
    
    Linux:
      #include <unistd.h>
    
    FreeBSD:
      #include <stdlib.h>

    //自主实现原理如下 

    [a] 编写守护进程的要点

    • 指定 umask 值,由环境继承来的默认权限有可能存在问题
    • 使该守护进程成为一个孤儿进程组中的唯一成员:
      • fork 之后终止父进程,此举确保不是进程组首进程,然后 setsid 创建新会话
      • 丢弃会话首进程身份(再次 fork),从而确保了该进程不会获得控制终端
    • 切换到正确的工作目录中
    • 如果没有关联的配置文件,则可以设置 SIG_IGN 忽略 SIG_HUP 信号
    • 关闭不需要的文件描术符,可以将常用的 0、1、2 三个描述符关联至 /dev/null,以防止意外 I/O

    [b] 样例

     1 #include <sys/types.h>
     2 #include <sys/time.h>
     3 #include <sys/stat.h>
     4 #include <sys/resource.h>
     5 #include <fcntl.h>
     6 #include <unistd.h>
     7 #include <stdio.h>
     8 #include <signal.h>
     9 
    10 void daemonize(const char *);
    11 char *workdir = "/";
    12 
    13 int
    14 main(void)
    15 {
    16     daemonize(workdir);
    17     while(1)
    18     {
    19         sleep(10);
    20     }
    21 }
    22 
    23 void
    24 daemonize(const char *workdir)
    25 {
    26     pid_t pid;
    27     int fd0, fd1, fd2;
    28     struct rlimit rl;
    29     struct sigaction sa;
    30     
    31     umask(0);
    32     chdir(workdir);
    33     
    34     pid = fork();
    35     if (pid < 0)
    36     {
    37         perror("fork");
    38     }
    39     else if (pid > 0)
    40     {
    41         _exit(0);
    42     }
    43     
    44     setsid();
    45     
    46     pid = fork();
    47     if (pid < 0)
    48     {
    49         perror("fork");
    50     }
    51     else if (pid > 0)
    52     {
    53         _exit(0);
    54     }
    55     
    56     if (-1 == getrlimit(RLIMIT_NOFILE, &rl))
    57     {
    58         perror("getrlimit");
    59     }
    60     if (rl.rlim_max == RLIM_INFINITY)
    61     {
    62         rl.rlim_max = 1024;
    63     }
    64     for(pid = 0; pid < rl.rlim_max; ++pid)
    65     {
    66         close(pid);
    67     }
    68     
    69     fd0 = open("/dev/null", O_RDWR);
    70     fd1 = dup2(fd0, 1);
    71     fd2 = dup2(fd0, 2);
    72 
    73     sa.sa_handler = SIG_IGN;
    74     sa.sa_flags = 0;
    75     sigemptyset(&sa.sa_mask);
    76     if (sigaction(SIGHUP, &sa, NULL) < 0)
    77     {
    78         perror("sigaction");
    79     }
    80 }

    ...

  • 相关阅读:
    nyoj112-指数运算
    nyoj51-管闲事的小明
    nyoj29-求置转换问题
    nyoj24-素数 距离问题
    nyoj22-素数求和问题
    nyoj23-取石子(一)
    nyoj4-ASCII码排序
    nyoj169-素数
    并查集:CDOJ1593-老司机破阵 (假的并查集拆除)
    线段树: CDOJ1598-加帕里公园的friends(区间合并,单点更新)
  • 原文地址:https://www.cnblogs.com/hadex/p/6206651.html
Copyright © 2011-2022 走看看