守护进程运用实例
1)守护进程可以直接在程序起始部分通过调用unistd中的daemon来将本进程设置为守护进程
2)可以用ps -axj | grep xx查看自己的守护进程启动情况
3)用kill可以杀死自己启动的守护进程
除上述直接调用,也可以自己编写自己想要的守护进程,下面是一个example,注意其中的fork两次,设置新会话setsid,更改目录到根目录chdir和重设文件权限掩码umask和关闭文件描述符:
/// \brief closeAll close all FDs >= a specified value /// /// \param fd void closeAll(int fd){ int fdlimit = sysconf(_SC_OPEN_MAX); while(fd < fdlimit ){ close(fd++); } } /// \brief daemon detach process from user and disapper into the background //returns -1 on failure, but you cannot do much except exit in that case //since we may already have forked. this is based on the BSD version, so //the caller is responsible for things like the umask, etc. /// /// \param nochdir /// \param noclose /// /// \return int daemon_own(int nochdir, int noclose){ // struct rlimit rl; struct sigaction sa; int fd0, fd1, fd2; umask(0); /*clear file creation mask*/ /*get maximum number of file descriptors*/ // if(getrlimit(RLIMIT_NOFILE, &rl) < 0){ //#ifdef DEBUG // std::cout << "cannot get file limit" << std::endl; //#endif // perror("getrlimit"); // } /*Become a session leader to lose controlling TTY*/ switch(fork()){ case 0: /*child*/ break; case -1: return -1; default: /*parent*/ _exit(0); /*exit the original process*/ } if(setsid() < 0){ /*new session & new group, shouldn't fail*/ return -1; } /*Ensure future opens won't allocate controlling TTYs*/ sa.sa_handler = SIG_IGN; /*ignore*/ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0){ #ifdef DEBUG std::cout << "cannot ignore SIGHUP" << std::endl; #endif perror("sigaction"); } /*dyke out this switch if you want to acquire a control tty in * the future -- not normally advisable for daemons*/ switch(fork()){ case 0: break; case -1: return -1; default: _exit(0); } /*change the current working directory to the root so * we won't prevent file systems from being unmounted*/ if(!nochdir) chdir("/"); if(!noclose){ closeAll(0); fd0 = open("/dev/null", O_RDWR); /*#include <fcntl.h>*/ fd1 = dup(0); fd2 = dup(0); } /*Initialize the log file*/ openlog("test", LOG_CONS, LOG_DAEMON); if(fd0 != 0 || fd1 != 1 || fd2 != 2){ syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } return 0; }
int main(int argc, char **argv){ if((daemon_own(0, 0)) < 0){ #ifdef DEBUG cout << "daemon error from daemon(int, int)" << endl; #endif perror("daemon"); exit(2); }
process(); return 0; }