守护进程

概念:

  PIG=PGID=PSID

  系统日志 syslogd服务

  守护进程的单例

主要函数:

  setsid  getpgrp  getpgid  getpgid  setpgid  fflush  openlog  syslog  closelog

  pid_t setsid(void);
  创建一个新的回话 成功返回pid_t失败返回-1
  获取进程组id:
  pid_t getpgrp(void);//方言   pid_t getpgrp(psid_t pid);//方言   pid_t getpgid(pid_t pid);
  将一个进程放到一个进程组中
  int setpgid(pid_t pid,pid_t pgid); 
  void openlog(const char * ident,int option,int facility);
  与系统日志建立关联
  ident:日志每行开头字符串 比如程序名称
  option:控制调用 可以有多个常用LOG_PID
  factility:指的是消息类型  LOG_KERN、LOG_USER、LOG_MAIL、LOG_DAEMON、LOG_AUTH、LOG_SYSLOG、LOG_LPR、LOG_NEWS、LOG_UUCP、LOG_CRON 或 LOG_AUTHPRIV
  具体man
  void syslog(int priority,const char * format,...);
  写日志
  priority:级别
  format:printf() 一样用。。
   void closelog(void);
  取消日志关联


 

规则:P374

  1.根据守护进程屏蔽字段 通常是umask(0)。如果守护进程需要创建文件需要根据需要设定

  2.fork子进程,父进程exit

  3.调用setsid创建一个新的会话

  4.处理信号

  5.改变当前工作目录为根目录chdir("/")

  6.关闭不需要的文件描述符getrlimit获取文件描述符的最大值

  7.重定向将0、1、2这三个文件描述符号 open("/dev/null").由于守护进程脱离了控制终端所以是不关心设备的。dup2(fd,012)

  8.编写日志 openlog

demo:  

 
  static int daemon_exit(int s)
  {
    //closelog();
    //fclose(fp);

    exit(0);
    //atexit()可以被调用
  }


  static
int daemonize(void)   {     int fd;     pid_t pid;     openlog("mydaemon",LOG_PID,LOG_DAEMON);     pid=fork();     if(pid<0)     {       syslog(LOG_ERR,"fork() %s",strerror(errno));       return -1;     }       if(pid>0)         exit(0);
    
struct sigaction sa;     sa.sa_handler = daemon_exit;
    sigemptyset(&sa.sa_mask);
    sigaddset(&sa.sa_mask,SIGINT);
    sigaddset(&sa.sa_mask,SIGTERM);
    sigaddset(&sa.sa_mask,SIGQUIT);
    sa.sa_flags = 0;
    sigaction(SIGINT,&sa,NULL);
    sigaction(SIGTERM,&sa,NULL);
    sigaction(SIGQUIT,&sa,NULL);     fd
=open("/dev/null",O_RDWR);     if(fd<0)     {       syslog(LOG_WARNING,"open() %s",strerror(errno));     }     else     {       dup2(fd,0);        dup2(fd,1);       dup2(fd,2);       if(fd>2)         close();     }     /*     //关闭所有文件描述符 如果有必要的话 有可能在一个程序里 子进程 变身为守护进程后 需要父进程打开的文件描述符 所以一下不合适 比如网路     struct rlimit r1;     if(getrlimit(RLIMIT_NOFILE,&r1)<0)       syslog(LOG_ERR,"getrlimit() %s",strerror(errno));     for(i=0;i<r1.rlim_max;i++)     {       close(i);     }     */     setsid();     chdir("/");     umask(0);     return 0;   }

  

原文地址:https://www.cnblogs.com/qingducx/p/4654296.html