守护进程,也是通常所说的daemon进程,是linux中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某些任务或等待处理某些发生的事件。通常在系统引导载入时启动,在系统关闭时终止。同时,守护进程还能完成许多系统任务。
由于在linux中,每一个系统与用户交互的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会关闭。但是守护进程却能够突破这种限制,它从被执行开始运转,直到接收到某些信号或整个系统关闭时才会退出。如果想让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进程变成一个守护进程。
创建守护进程过程
1.创建子进程,父进程退出
子进程变成孤儿进程,然后由1号init进程收养。
2.子进程创建新会话
调用setsid创建新的会话,摆脱原会话,原进程组,原终端的控制,自己成为新会话的组长。
3.将当前目录改为根目录
正在运行的进程文件系统不能卸载,如果目录要回退,则此时进程不能做到,为了避免这种麻烦,以根目录为当前目录。
4.重设文件权限掩码
子进程的文件权限掩码是复制的父进程的,不重新设置的话,会给子进程使用文件带来诸多麻烦。
5.关闭不需要的文件描述符
子进程的文件描述符也是从父进程复制来的,那些不需要的文件描述符永远不会被守护进程使用,会白白的浪费系统资源,还可能导致文件系统无法结束。
具体例程如下
//daemon
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
int i,fd;
char *buf = "This is a Daemon\n";
pid = fork();//第一步
if(pid < 0)
{
printf("Error fork\n");
exit(1);
}
else if(pid > 0)
{
exit(0);//父进程退出
}
setsid(); //第二步
chdir("/");//第三步
umask(0);//第四步
for(i = 0; i < getdtablesize();i++)
{
close(i);
}
//已创建完守护进程,正式进入守护进程工作
while(1)
{
if(fd = open("/tmp/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600) < 0)
{
printf("Open file error\n");
exit(1);
}
write(fd,buf,strlen(buf)+1);
close(fd);
sleep(5);
}
exit(0);
}
执行结果