• 拾遗: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 }

    ...

  • 相关阅读:
    无法作为数据库主体执行,因为主体 "dbo" 不存在、无法模拟这种类型的主体,或您没有所需的权限
    sql server 2008收缩数据库日志
    c#基本语法
    写点东西
    转载 程序人生成长发展中的一些感悟
    C#基本问题
    对象入门
    21k8s部署discuz
    Mysql基础管理
    将枚举作为参数,迭代枚举。Passing Enum type as a parameter
  • 原文地址:https://www.cnblogs.com/hadex/p/6206651.html
Copyright © 2020-2023  润新知