在Linux中专门提供了一个函数来完成这个daemon化的过程,这个函数的原型如下 int daemon (int __nochdir, int __noclose); 如果__nochdir的值为0,则将切换工作目录为根目录;如果__noclose为0,则将标准输入,输出和标准错误都重定向到/dev /null。 经过这个函数调用后的程序将运行在后台,成为一个daemon程序,而linux下大多的服务都是以此方式运行的。 我们来看一个简单的例子。例如编写例子程序test.c #include <unistd.h> #include <stdio.h> int do_sth() { //Add what u want return 0; } int main() { daemon(0,0); while ( 1 ) { do_sth(); sleep(1); } } 编译并运行 [leconte@localhost daemon]$ gcc -o test test.c [leconte@localhost daemon]$ ./test 程序进入了后台,通过ps查看进程情况,可以看到进程的父进程id为1,即init进程 用lsof查看test进程所打开的文件,可以看到文件描述符0,1,2都被重定向到/dev/null 并且能够看到,进程的当前工作目录(cwd)为根目录/,daemon函数已经帮我们完成了daemon化的过程,接下来我们只需要关注于程序功能 的实现了。 daemon函数用于创建守护进程,实现原理如下: #include <unistd.h> int daemon(int nochdir, int noclose); 1. daemon()函数主要用于希望脱离控制台,以守护进程形式在后台运行的程序。 2. 当nochdir为0时,daemon将更改进城的根目录为root(“/”)。 3. 当noclose为0是,daemon将进城的STDIN, STDOUT, STDERR都重定向到/dev/null。 daemon的实现大致如下: int daemon( int nochdir, int noclose ) { pid_t pid; if ( !nochdir && chdir("/") != 0 ) //如果nochdir=0,那么改变到"/"根目录 return -1; if ( !noclose ) //如果没有noclose标志 { int fd = open("/dev/null", O_RDWR); if ( fd < 0 ) return -1; /* 重定向标准输入、输出、错误到/dev/null, 键盘的输入将对进程无任何影响,进程的输出也不会输出到终端 */ dup(fd, 0); dup(fd, 1); dup(fd, 2); close(fd); } pid = fork(); //创建子进程. if (pid < 0) //失败 return -1; if (pid > 0) _exit(0); //返回执行的是父进程,那么父进程退出,让子进程变成真正的孤儿进程. //创建的 daemon子进程执行到这里了 if ( setsid() < 0 ) //创建新的会话,并使得子进程成为新会话的领头进程 return -1; return 0; //成功创建daemon子进程 } 摘要:针对Linux环境下的守护进程daemon,分析了一般性守护进程的编写方法,并提出若干见解,通过总结归纳进而为设计和开发守护进程提供了有意的参考,给出了基于Linux守护进程实现的主要思想。