守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
Linux 的大多数服务器就是用守护进程实现的。比如,Internet 服务器 inetd,Web 服务器 httpd 等。
在终端敲:ps axj
从上图可以看出守护进行的一些特点:
一般情况下,守护进程可以通过以下方式启动:
signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTSTP,SIG_IGN); signal(SIGHUP ,SIG_IGN);
if( pid = fork() ){ // 父进程 exit(0); //结束父进程,子进程继续 }
setsid();
if( pid=fork() ){ // 父进程 exit(0); // 结束第一子进程,第二子进程继续(第二子进程不再是会话组长) }
// NOFILE 为 <sys/param.h> 的宏定义 // NOFILE 为文件描述符最大个数,不同系统有不同限制 for(i=0; i< NOFILE; ++i){// 关闭打开的文件描述符 close(i); }
chdir("/");
umask(0);
signal(SIGCHLD, SIG_IGN);
#include <unistd.h> #include <signal.h> #include <fcntl.h> #include <sys/syslog.h> #include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <time.h> int init_daemon(void) { int pid; int i; // 1)屏蔽一些控制终端操作的信号 signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTSTP,SIG_IGN); signal(SIGHUP ,SIG_IGN); // 2)在后台运行 if( pid=fork() ){ // 父进程 exit(0); //结束父进程,子进程继续 }else if(pid< 0){ // 出错 perror("fork"); exit(EXIT_FAILURE); } // 3)脱离控制终端、登录会话和进程组 setsid(); // 4)禁止进程重新打开控制终端 if( pid=fork() ){ // 父进程 exit(0); // 结束第一子进程,第二子进程继续(第二子进程不再是会话组长) }else if(pid< 0){ // 出错 perror("fork"); exit(EXIT_FAILURE); } // 5)关闭打开的文件描述符 // NOFILE 为 <sys/param.h> 的宏定义 // NOFILE 为文件描述符最大个数,不同系统有不同限制 for(i=0; i< NOFILE; ++i){ close(i); } // 6)改变当前工作目录 chdir("/tmp"); // 7)重设文件创建掩模 umask(0); // 8)处理 SIGCHLD 信号 signal(SIGCHLD,SIG_IGN); return 0; } int main(int argc, char *argv[]) { init_daemon(); while(1); return 0; }
原文地址:http://blog.csdn.net/tennysonsky/article/details/45970087