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

      

  • 相关阅读:
    php安装yaf,memcache,memcached模块
    django的ORM操作
    Composer简介
    MySQL中exists和in的区别及使用场景
    MySQL事务原理浅析
    MySQL JOIN原理
    mysql 子句、子查询、连接查询
    多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
    数据库多表连接方式介绍-HASH-JOIN
    MySQL中的case when 中对于NULL值判断的坑
  • 原文地址:https://www.cnblogs.com/qingducx/p/4654296.html
Copyright © 2011-2022 走看看