一、标准步骤
创建守护进程大概分以下几步,但是还要关闭一些文件描述符才行:
#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; }
沉默,不进行标准输出:参考
守护进程中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; }