守护进程没有控制终端,在后台运行,又叫后台进程。
守护进程的编程规则:1. 调用fork,创建子进程,并退出父进程*/
/*2. 脱离终端,成为会话组的组长,主进程*/
/*3. 改变家目录为根目录*//*
/*4. 关闭所有打开过的文件*/
/*5.把输出重定向到日志文件中*/
要成为守护进程,必须杀死自己的父亲,纂位,自己当组长,以前的那些父亲手下的文件大臣统统“杀死”,改变自己的皇宫住址,创建自己的输出方式。
例程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#define LOG_FILE "/tmp/my.log"
int Daemon(int nochdir, int noclose)
{
/*1. 调用fork,创建子进程,并退出父进程*/
pid_t p = fork();
if (p == -1) {
perror("fork failed");
return -1;
}
if (p > 0) {
_exit(0);
}
/*1000微妙*/
usleep(1000);
/*2. 脱离终端,成为会话组的组长,主进程*/
p = setsid();
if (p == -1) {
perror("setsid failed.");
return -1;
}
/*3. 改变家目录为根目录*/
if (! nochdir) {
chdir("/");
}
/*4. 关闭所有打开过的文件*/
if (! noclose) {
int dtable_size = getdtablesize();//返回每个进程所能打开的最大的文件数量
for (;dtable_size >= 0; --dtable_size) {
close(dtable_size);
}
}
/*5.把输出重定向到日志文件中*/
int null_fd = open("/dev/null", O_RDWR);
dup2(null_fd, STDIN_FILENO);//输入为NULL
int log_fd = open(LOG_FILE, O_WRONLY | O_APPEND| O_CREAT, 0666);
if (log_fd != -1) {
dup2(log_fd, STDOUT_FILENO);
//dup2(log_fd, STDERR_FILENO);
}
return 0;
}
int main()
{
printf("pid = %d, ppid = %d\n", getpid(), getppid());
Daemon(0, 0);
while (1) {
printf("daemon is running, %d, %d\n", getpid(), getppid());
sleep(1);
}
return 0;
}