【问题标题】:Daemon Not Stopping in linux守护进程在linux中没有停止
【发布时间】:2011-05-10 02:03:36
【问题描述】:

我使用了以下指南 (http://peterlombardo.wikidot.com/linux-daemon-in-c),它运行良好且美观,接受它不会杀死。

Main.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);
}

singal_handler.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

然后我跑

杀死进程

日志

INFROMATIONAL,开始日期

INFORMATIONAL, dae Processed((null), 1)

INFORMATIONAL, dae Processed((null), 2)

INFORMATIONAL, dae Processed((null), 3)

警告,收到 SIGTERM 信号。

INFORMATIONAL, dae Processed((null), 4)

INFORMATIONAL, dae Processed((null), 5)

这该死的东西没有停止吗?任何想法谢谢

【问题讨论】:

    标签: c++ linux daemon


    【解决方案1】:

    由于您正在处理TERM 信号,其默认行为被禁用。

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

    这是一个允许清理但不使用atexit()的实现:

    signal_handler.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
    

    ma​​in.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);
    }
    

    【讨论】:

    • 但是如果我想在while循环之后执行清理操作怎么办
    • 可以使用atexit()注册退出函数。
    • 如果我得到signal(..) 函数来设置一个变量,我可以用它来打破while循环
    • signal_handler 开关中断之前添加了一个全局int shutdown = 0 设置为shutdown = 1。这样主循环就会中断并在主循环下执行清理,感谢 Frederic,你让我得到了这个解决方案。 :D
    • @Angel.King.47,只是对 g_terminated 布尔变量做了同样的事情 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2012-08-29
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多