创建子进程,父进程退出
子进程中创建新会话
改变当前目录为根目
重设文件权限掩码
关闭文件描述符
同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。
这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。
在上面的第二步之后,守护进程已经与所属的控制终端失去了联系。
因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件(常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。
for(i=0;i
守护进程退出处理
当用户需要外部停止守护进程运行时,往往会使用 kill命令停止该守护进程。
所以,守护进程中需要编码来实现kill发出的signal信号处理,达到进程的正常退出。
//守护进程的完整实例(每隔10s在/tmp/dameon.log中写入一句话)
#include
#include
#include
#include
#include
#include
#include
#include #define MAXFILE 65535 volatile sig_atomic_t _running = 1; void sigterm_handler(int arg) { _running = 0;
} int main() { pid_t pc, pid; int i, fd, len; char *buf = "this is a Dameon\n"; len = strlen(buf); //第一步 pc = fork(); if(pc < 0) { printf("error fork\n"); exit(1); } else if(pc > 0) { exit(0); } //第二步 setsid(); pid = fork();//与终端完全脱离[1] if (pid < 0) { perror("fork error");} else if (pid > 0) { exit(0);} //第三步 chdir("/"); //第四步 umask(0); //第五步 for(i = 0;i < MAXFILE; i++) { close(i);} signal(SIGTERM, sigterm_handler);while( _running ) { if((fd = open("/tmp/dameon.log", O_CREAT | O_WRONLY | O_APPEND, 0600)) < 0) { perror("open"); exit(1); } write(fd, buf, len); close(fd); usleep(10 * 1000);//10毫秒 }
}