一、守护进程的概念
守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端,并且周期性的执行某种任务或者等待处理某些发生的时间。守护进程是一种很有用的进程。Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond等。
二、守护进程的查看
查看守护进程的命令:ps ajx
参数a:不仅列出当前用户的进程,也列出所有其他用户的进程。
参数 j:不仅列出有控制终端的进程,也列出所有无控制终端的进程。
参数 x:列出与作业控制相关的信息。
从上图可以看出守护进程没有控制终端(TTY为?),基本都是超级用户启动,终端进程组ID为-1的特点。
三、守护进程的创建
(1).调用umask将文件模式创建屏蔽字设置为0
(2).调用fork,父进程退出(exit)
(3).调用setsid创建一个新会话
(4).将当前工作目录更改为根目录
(5).关闭不再需要的文件描述符
(6).忽略SIGCHLD信号
四、守护进程的代码
在下面的代码中,进行了俩次fork。这样做的原因是:
第1次fork的作用是让shell 认为本条命令 已经终止,不用挂在终端输入上。还有一个作用是为后面setsid服务。setsid的调用者不能是进程组组长(group leader). 此时父进程是进程组组长。
第2次fork不是必须的。fork第二次主要目的是。防止进程再次打开一个控制终端。因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
void mydaemon()
{
pid_t pid;
//(1)调用umask将文件模式创建屏蔽字设置为0
umask(0);
//(2)创建子进程,退出父进程
if(pid = fork())
{
exit(0);
}
else if(pid < 0)
{
printf("error fork\n");
exit(1);
}
//(3)调用setsid创建一个新会话
setsid();
//第二次fork
pid = fork();
if(pid != 0)exit(0);
//(4)将当前工作目录更改为根目录
chdir("/");
//(5)关闭不再需要的文件描述符
close(0);
close(1);
cloae(2);
//(6)忽略SIGCHLD信号
signal(SIGCHLD,SIG_IGN);
}
int main()
{
mydaemon();
while();
return 0;
}
结果如下图所示: