代码之家  ›  专栏  ›  技术社区  ›  Angel.King.47

守护进程在linux中未停止

  •  3
  • Angel.King.47  · 技术社区  · 15 年前

    我使用了下面的指南(http://peterlombardo.wikidot.com/linux-daemon-in-c),它工作得很好,很漂亮,接受它不会杀人。

    主.cpp

    //Global Directives
    //#define DEBUG 1
    #define DAE_NAME "dae"
    #define DAE_PID "/var/run/dae.pid"
    
    //Includes
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sstream>
    #include <string>
    #include <fstream>
    #include <iomanip>
    #include <vector>
    #include <syslog.h>
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <unistd.h>
    #include <assert.h>
    #include <signal.h>
    
    //Namespace (System)
    using namespace std;
    
    //Classes
    #include "class.h"
    
    //Structures
    #include "struct/struct.h"
    
    //Functions
    #include "function/signal_handler.h"
    
    void usage(int argc, char *argv[]) {
        if (argc >=1) {
            printf("Usage: %s -h -nn", argv[0]);
            printf("  Options:n");
            printf("      -ntDon't fork off as a daemon.n");
            printf("      -htShow this help screen.n");
            printf("n");
        }
    }
    
    int main(int argc, char *argv[]) {
    
    #if defined(DEBUG)
        int daemonize = 0;
    #else
        int daemonize = 1;
    #endif
    
        // Setup signal handling before we start
        signal(SIGHUP, signal_handler);
        signal(SIGTERM, signal_handler);
        signal(SIGINT, signal_handler);
        signal(SIGQUIT, signal_handler);
    
        //Print Usage Information
        int c;
        while((c = getopt(argc, argv, "nh|help")) != -1) {
            switch(c){
                case 'h':
                 usage(argc, argv);
                    exit(0);
                    break;
                case 'n':
                    daemonize = 0;
                    break;
                default:
                 usage(argc, argv);
                    exit(0);
                    break;
            }
        }
    
        // Setup syslog logging
    #if defined(DEBUG)
        setlogmask(LOG_UPTO(LOG_DEBUG));
        openlog(DAE_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
    #else
        setlogmask(LOG_UPTO(LOG_INFO));
        openlog(DAE_NAME, LOG_CONS, LOG_USER);
    #endif
    
        //------------
        //Daemon Setup
        //------------
        pid_t pid, sid;
    
        if (daemonize) {
            syslog(LOG_INFO, "Starting %s", DAE_NAME);
    
            /* Fork off the parent process */
            pid = fork();
            if (pid < 0) {
                exit(EXIT_FAILURE);
            }
            /* If we got a good PID, then
               we can exit the parent process. */
            if (pid > 0) {
                exit(EXIT_SUCCESS);
            }
    
            /* Change the file mode mask */
            umask(0);
    
            /* Create a new SID for the child process */
            sid = setsid();
            if (sid < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
            }
    
            /* Change the current working directory */
            if ((chdir("/")) < 0) {
                /* Log the failure */
                exit(EXIT_FAILURE);
            }
    
            /* Close out the standard file descriptors */
            close(STDIN_FILENO);
            close(STDOUT_FILENO);
            close(STDERR_FILENO);
        }
    
        int count = 1;
    
        //-------
        //Process
        //-------
        while (1){
            process();
    
            syslog (LOG_INFO, "%s Processed(%s, %d)", DAE_NAME, getlogin(), count);
    
            count++;
        }
    
        syslog (LOG_INFO, "Exiting Daemon %s", DAE_NAME);
    
        closelog (); //Close the Connection
    
        exit(EXIT_SUCCESS);
    }
    

    信号处理程序.h

    #ifndef SIGNAL_HANDLER_H_
    #define SIGNAL_HANDLER_H_
    
    void signal_handler(int sig) {
    
        switch(sig) {
            case SIGHUP:
                syslog(LOG_WARNING, "Received SIGHUP signal.", DAE_NAME);
                break;
            case SIGTERM:
                syslog(LOG_WARNING, "Received SIGTERM signal.", DAE_NAME);
                break;
            default:
                syslog(LOG_WARNING, "Unhandled signal ", DAE_NAME);
                break;
        }
    }
    
    #endif
    

    命令行

    所以在命令行中我运行这个

    ./dae公司

    然后我就跑

    杀死普罗基德

    原木

    非常规,起始dae

    信息性,已处理dae((空),1)

    信息性,已处理dae((空),2)

    信息性,已处理dae((空),3)

    警告,收到信号。

    信息性,已处理dae((空),4)

    信息性,已处理dae((空),5)

    这该死的事情不会停止吗?有什么想法吗谢谢

    1 回复  |  直到 15 年前
        1
  •  5
  •   Frédéric Hamidi    12 年前

    因为你在处理 TERM 信号,其默认行为被禁用。

    您需要显式调用 exit() 从你的信号处理程序终止你的程序。

    下面是一个允许清理但不使用 atexit() :

    信号处理器.h

    #ifndef SIGNAL_HANDLER_H_
    #define SIGNAL_HANDLER_H_
    
    extern bool g_terminated;
    
    void signal_handler(int sig) {
    
        switch(sig) {
            case SIGHUP:
                syslog(LOG_WARNING, "Received SIGHUP signal.", DAE_NAME);
                break;
            case SIGTERM:
                syslog(LOG_WARNING, "Received SIGTERM signal.", DAE_NAME);
                g_terminated = true;
                break;
            default:
                syslog(LOG_WARNING, "Unhandled signal ", DAE_NAME);
                break;
        }
    }
    
    #endif
    

    主.cpp

    bool g_terminated = false;
    
    int main(int argc, char *argv[])
    {
        .
        .
        .
    
        //-------
        //Process
        //-------
        while (!g_terminated) {
            process();
    
            syslog (LOG_INFO, "%s Processed(%s, %d)", DAE_NAME, getlogin(), count);
    
            count++;
        }
    
        // Cleanup...
    
        exit(EXIT_SUCCESS);
    }