守护进程

守护进程

守护进程介绍

在Linux 或者 UNIX 操作系统中在系统的引导的时候会开启很多服务,这些服务就叫作守护进程 。
守护进程是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件 。
由于在 Linux 中,每 个系统与用户进行交流的界面称为终端,每 个从此终端运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关
闭时,相应的进程 会自动关闭 ,但是守护进程却能够突破这种限制,它从被执行时开始运转,直到整个系统关闭时才退出 ,如果想让某个进程不因为用户或终端或其他地变化而受到关闭
,那么就必须把这个进程变成一个守护进程。
一个简单的守护进程的步骤如下所述:

  1. 创建子进程,父进程退出
  2. 调用setsid函数在子进程中创建新会话。
    在建守护进程时为什么要调用setsid函数呢?由于创建守护进程的第1 步调用fork 函数创建子进程,再将父进程退出 由于在第1步调用了 fork 函数时,子进程全盘拷贝
    了父进程的会话期 进程组 控制终端等,虽然父进程退出了,但 话期、进程组 控制终
    端等并没有改变,因此,还不是真正意义上的独立 setsid函数能够使进程完全独立出来,
    从而摆脱其他进程的控制。
  3. 改变当前目录为根目录
  4. 重设文件权限掩码
  5. 关闭文件描述符
    总之,这些步骤都是为了摆脱父进程的影响。

一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAXFILE 65535
int main()
{
pid_t pc;
int i,fd,len;
const char *buf = "this is a Daemon\n";
len = strlen(buf);
pc = fork();
if(pc < 0)
{
printf("error fork\n");
exit(1);
}else if(pc > 0){
exit(0);
}//1
setsid();//2
chdir("/");//3
umask(0);//4
for(i = 0;i < MAXFILE;i++)
{
close(i);
}//5
while(1){
if((fd = open("/tmp/daemon.log",O_CREAT|O_WRONLY|O_APPEND,0600)) <0)
{
perror("open");
exit(1);
}
write(fd,buf,len+1);
close(fd);
sleep(10);
}
return 0;
}