• 守护进程


    一、标准步骤

      创建守护进程大概分以下几步,但是还要关闭一些文件描述符才行:

    #include <unistd.h>  
    #include <stdio.h>
    #define RUNNING_DIR /tmp
    int main(){
        pid_t pid;
        pid=fork();
        if(pid!=0)exit(0); // 如果创建失败或者为父进程则退出
        printf("Running...");
        setsid();          // obtain a new process grop
        for(int i=gettabsize();i>=0;i--){close(i);}
        i=open("/dev/null",O_RDWR);
        dup(i); dup(i);
        umask(027);
        chdir(RUNNING_DIR);
        
        signal(SIGCHLD,SIG_IGN);
        signal(SIGTSTP,SIG_IGN);
        signal(SIGTTOU,SIG_IGN);
        signal(SIGTTIN,SIG_IGN);
        signal(SIGHUP,HelperDaemon::signalHandler);  // hangup
        signal(SIGTERM,HelperDaemon::signalHandler); // kill
        while(1); return 0; 
    }

      沉默,不进行标准输出:参考

      关于dup: 参考   参考

      谷歌图书:参考   参考

      守护进程中setsid、nohub等的参考资料:参考

    二、实例

    #include <iostream>
    #include <unistd.h>
    #include <cstdio>
    #include <cstdlib>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/param.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <time.h>
    
    class WSDaemon
    {
    public:
        WSDaemon(){}
        ~WSDaemon(){}
        void daemonize();
        void wsExit(std::string cause, int code)
        {
            std::cerr << cause << std::endl;
            exit(code);
        }
    };
    
    #if 1
    void WSDaemon::daemonize()
    {
        int pid;
        int i;
        
        if(getppid() == 1)
        {
            return;    //wsExit("already running.", 0);
        }
    
        // 1. fork
        pid = fork();
        std::cout << pid << std::endl;
    
        if(pid < 0)
            wsExit("fork error.", 1);
    
        if(pid > 0)
            exit(0);
            //wsExit("parent exit.", 0);
    
        // 2. child process detach from parent and creat new session
        setsid();
        
        // 3. switch to a working directory that cannot be uninstalled.
        if(chdir("/") < 0) wsExit("change dir error.", 1);
    
        // 4. change the file permission mask to prevent inheriting to the parent process permission, result in file operation failure.
        // (~0) & mode == 0777 & mode
        // 0777 : 0B777 
        umask(0);
        
        // 5. close file description inherited from parent process.
        for(i=0; i < NOFILE; i++) close(i);
        
        // 6. redirect standard output to prevent byte stream from accidentally outputting from terminal. 
        /*
        i = open("/dev/null", O_RDWR);
        dup(i);
        dup(i);
        */
    
        return;
    }
    #endif
    
    
    #if 0
    void WSDaemon::daemonize()
    {
        int i;
        if(getppid() ==1)
        {
            std::cerr << "There is already a daemon running." <<std::endl;
            return;
        }
    
        i = fork();
    
        if(i<0) exit(1);
        if(i>0) exit(0);
    
        setsid();
    
        for(i = getdtablesize();i>=0;i--)
        {
            close(i);
        }
        
        i = open("/dev/null", O_RDWR);
        dup(i);
        dup(i);
        umask(027);
        chdir("/tmp");
    }
    
    #endif
    
    
    int main()
    {
        FILE *fp;
        time_t t;
    
        WSDaemon wsd;
        wsd.daemonize();
    
        while(1)
        {
            // wait 5s
            sleep(5);
            fp = fopen("/home/alex/Desktop/webs-qt-Online/test.log", "a+");
            if(fp >= 0)
            {
                time(&t);
                fprintf(fp, "current time is : %s
    ", ctime(&t));
                fclose(fp);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    架构阅读笔记4
    python读取docx内容
    python转换doc为docx
    使用Navicat连接oracle问题及解决
    扩充虚拟机磁盘
    虚拟机无法打开内核
    六个常见属性场景
    架构阅读笔记3
    架构学习
    PHP中的加密方式有如下几种
  • 原文地址:https://www.cnblogs.com/abnk/p/11399080.html
Copyright © 2020-2023  润新知