现在的位置: 首页 > 综合 > 正文

守护进程介绍

2013年12月05日 ⁄ 综合 ⁄ 共 1438字 ⁄ 字号 评论关闭

【守护进程介绍】

Linux系统启动时往往要启动很多的系统服务程序,比如apache,ftp,telnet等。这些系统服务程序往往运行在后台,没有控制终端,在系统引导装入时启动,在系统关闭时终止,周期性的执行某项任务或者等待处理某项任务。这样的进程叫守护进程或者精灵进程。

 

编写守护进程一般是在普通进程基础上,根据守护进程的特点进行改造。编程实现守护进程要遵循的几个要点:

 

1.父进程是init进程,后台执行

用fork函数创建子进程,并将父进程终止,这样子进程成为孤儿进程被init进程收养,并在后台执行。

 

2.脱离控制终端,创建新的会话和进程组,并成为首进程

进程组是一个或者多个进程的集合,进程组有对应的组ID,是由领头进程的进程号决定的;会话是一个或者多个进程组的集合,每个会话也有一个领头进程。每个进程属于一个进程组,每个进程组又属于一个会话。当用户从终端登陆系统时,系统会创建一个会话,该终端上启动的进程都会被系统规划到会话的进程组中。会话中的进程是通过会话的领头进程与一个控制终端相连。

 

由于守护进程没有控制终端,而通过fork创建的子进程继承了父进程的控制终端、进程组和会话,因此必须重新创建会话,以脱离父进程的影响。

pid_t setsid(void);  //返回调用进程的会话ID

前提:调用setsid的进程不能为一个进程组的领头进程,fork的子进程一定满足

结果:创建新的会话,调用setsid的子进程成为会话中唯一进程组,组ID=调用进程的ID.

 

3.更改当前工作目录

fork的子进程继承父进程的工作目录,但是如果作为守护进程使用,进程没有结束之前,工作目录不能被卸载。所以一般将工作目录使用chdir()更改到根目录下。

 

4.关闭文件描述符,重定向标准输入、输出、错误

需要关闭从父进程继承来的无需使用的文件描述符。运行在后台,不需要在终端有任何输出信息。

 

5.重设权限

屏蔽其他用户对守护进程创建的临时文件的访问权限。

 

【代码实现】

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>

void daemon_def(void)
{
 pid_t pid;
 int fd;
 pid = fork();
 if(pid<0)
 {
  perror("Fail to creat child process./n");
  return;

 }
 else if(pid>0)
 {
  exit(0);
 }
 else
 {
  pid = setsid();
  if(pid<0)
  {
   perror("Setsid failed./n");
   return;
  }
  chdir("/");
  if((fd = open("/dev/null",O_RDWR,0))==-1)
  {
   perror("Can't open dev file./n");
   return;
  }
  dup2(fd,STDIN_FILENO);
  dup2(fd,STDOUT_FILENO);
  dup2(fd,STDERR_FILENO);
  umask(0027);
  return;   //这里错用成exit,子进程直接终止了,即main没有执行到sleep就结束了。ps看不到。 
 }
}

 

int main(void)
{
 daemon_def();
 sleep(1000);
 return 0;
}

抱歉!评论已关闭.