2014-11-05 16 views
0

因此,我正在编写一个将在Linux系统中作为后台进程运行的程序,并且我一直在设置一个守护进程函数,以便在后台运行进程。我需要知道的是,我是否应该在主类中声明一个对象来运行守护进程函数,或者是否应该创建守护进程函数,并且它是静态的两个子函数。代码如下,有没有更好的方法来做到这一点,或者是一种比另一种更可取的方法?谢谢。从主循环调用守护进程函数?

#include "../Headers/LogMonitor.h" 

#define RUNNING_DIR "/tmp" 
#define LOCK_FILE "exampled.lock" 
#define LOG_FILE "exampled.log" 

LogMonitor::LogMonitor() { 
    // TODO Auto-generated constructor stub 

} 

LogMonitor::~LogMonitor() { 
    // TODO Auto-generated destructor stub 
} 

int main(int argc, const char* argv[]) 
{ 
    // Daemonize the program to run in the background 
    LogMonitor::daemonize(); 
} 

void LogMonitor::signal_handler(int sig) 
{ 
    switch(sig) { 
    case SIGHUP: 
     log_message(LOG_FILE,"hangup signal caught"); 
     break; 
    case SIGTERM: 
     log_message(LOG_FILE,"terminate signal caught"); 
     exit(0); 
     break; 
    } 
} 

void LogMonitor::log_message(const char *filename, const char *message) 
{ 
    FILE *logfile; 
    logfile=fopen(filename,"a"); 
    if(!logfile) return; 
    fprintf(logfile,"%s\n",message); 
    fclose(logfile); 
} 

void LogMonitor::daemonize() 
{ 
    int i,lfp; 
    char str[10]; 

    if(getppid()==1) return; // Check if already a daemon 

    i = fork(); 
    if (i < 0) exit(1);   // Fork error 
    if (i > 0) exit(0);   // Parent exits 

    setsid();     // Obtain a new process group 

    for (i = getdtablesize(); i >= 0; --i) close(i); // Close all descriptors 

    i = open("/dev/null",O_RDWR);      // stdin 
    dup(i);            // stdout 
    dup(i);            // stderr 

    umask(027);           // Set newly created file permissions 

    chdir(RUNNING_DIR);         // Change running directory 

    lfp = open("exampled.lock",O_RDWR|O_CREAT,0640); 
    if (lfp < 0) exit(1);        // Can't open 
    if (lockf(lfp,F_TLOCK,0) < 0) exit(0);    // Can't lock 
    sprintf(str,"%d\n", getpid()); 
    write(lfp,str,strlen(str));       // Record pid to lockfile 

    signal(SIGCHLD,SIG_IGN);       // Ignore child 
    signal(SIGTSTP,SIG_IGN);       // Ignore tty signals 
    signal(SIGTTOU,SIG_IGN); 
    signal(SIGTTIN,SIG_IGN); 
    signal(SIGHUP, LogMonitor::signal_handler);     // Catch hangup signal 
    signal(SIGTERM, LogMonitor::signal_handler);     // Catch kill signal 
} 

回答

1

现代守护进程不应该作为自己的后台。相反,只需在前台运行它,并让调用者(即/etc/init.d下的脚本)选择将其守护 - start-stop-daemon(8)常用,但systemd可以自行完成。

+0

我没有得到downvote?!?这很好地回答了问题_“代码在下面,是否有更好的方法来做到这一点,或者是一种比另一种更好的方法?”_ – 2014-11-05 21:18:04

+0

这似乎是一个非常合理的答案。如果您在启动守护进程之前必须执行一些逻辑,请将其放入'/ etc/init.d'脚本中(检查PID文件或您拥有的文件)。该进程应该是守护进程,而不是守护进程管理器;我们有十几个工具,没有任何理由让你编写另一个定制的Puppet类。你越聪明,工作的可能性就越大,而且这很简单。 – ssube 2014-11-05 21:19:41