zoukankan      html  css  js  c++  java
  • 守护进程

    概念:

      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;   }

      

  • 相关阅读:
    Lc617_合并二叉树
    Lc257_二叉树的所有路径
    Lc222_完全二叉树的节点个数
    记github下载上传遇到的各种问题
    Lc101_对称二叉树
    Lc222_翻转二叉树
    二叉树的dfs 与 bfs (递归遍历)
    全球最火的程序员学习路线!没有之一!3天就在Github收获了接近1w点赞
    大二逃课总结的1.2w字的计算机网络知识!扫盲!
    「IDEA插件精选」安利一个IDEA骚操作:一键生成方法的序列图
  • 原文地址:https://www.cnblogs.com/qingducx/p/4654296.html
Copyright © 2011-2022 走看看