1、概念:守护进程是在后台运行的不受终端控制的进程,通常守护进程在系统启动时自动运行,守护进程的名称通常以d结尾,比如sshd、xinetd、crond等。
2、创建守护进程的步骤:
a、调用fork(),创建新进程,它会是将来的守护进程;
b、在父进程中调用exit(),保证子进程不是进程组组长;(进程组组长不能创建新的会话)
c、调用setsid创建新的会话期; pid_t setsid(void); 如果调用进程不是进程组组长,就可以创建一个新的会话期。调用者进程号码称为会话期的号码,和会话期中唯一进程组的号码
d、将当前目录改为根目录;
e、将标准输入、标准输出、标准错误重定向到/dev/null;
#include<unistd.h> #include<sys/types.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<signal.h> #define ERR_EXIT(m)\ do\ {\ perror(m);\ exit(EXIT_FAILURE);\ }while(0) //宏要求一条语句 int setup_daemon(void); int main() { setup_daemon();
for(;;); //实际上直接调用daemon()函数也可以实现。 //void daemon(int nochdir,int noclose); nochdir:0将当前目录更改至"/" //noclose:0 将标准输入、标准输出、标准错误重定向到/dev/null //printf("test...");//没有输出 return 0; } //创建完新会话,调用者进程将成为新会话期的领头进程; //调用者进程会成为新会话中唯一进程组的组长; //并且新的会话期没有控制终端;在后台运行; int setup_daemon(void) { pid_t pid; pid=fork(); if(pid==-1) ERR_EXIT("fork error"); else if(pid>0) exit(EXIT_SUCCESS); setsid(); chdir("/"); close(0); close(1); close(2); open("/dev/null",O_RDWR);//0指向/dev/null dup(0);//找到最小的1指向0 dup(0);//找到最小的2指向0 return 0; }
实际系统中提供了一个函数,实现上述功能:void daemon(int nochdir,int noclose);的参数都置为1,就不会重定向,也不会定位到根目录,主要用于开发调试的时候使用。