首页 > 代码库 > Linux守护进程

Linux守护进程

守护进程(daemon)是在后台运行且不与任何控制终端关联的进程。

与终端脱离有两个目的:

  1. 避免进程运行过程中将信息输出到终端
  2. 避免进程被终端产生的信息中断

创建守护进程前首先需要理解几个概念:进程组、会话、控制终端。

 

每个进程除了有一进程ID(PID)之外,还属于一个进程组。

进程组是一个或多个进程的集合,每个进程组有一个进程组ID。

每个进程组有一个组长进程(process group leader),组长进程的PID等于它的进程组ID。

 

会话(session)是一个或多个进程组的集合。

会话中的多个进程组可被分为一个前台进程组以及多个后台进程组。

一个会话有一个控制终端。

 

进程可以通过调用setsid函数创建一个新会话。

pid_t setsid(void);

有一点需要注意:调用此函数的进程不能是一个进程组的组长。调用该函数会发生以下3件事:

(1) 该进程变成新会话的会话首进程(session leader)

(2) 该进程成为一个新进程组的组长进程

(3) 该进程没有控制终端

 

创建守护进程的步骤如下:

(1) 创建子进程,父进程退出

    调用fork,然后父进程exit,这么做实现下面两点:第一、如果本进程是从前台作为一个shell命令启动的,当父进程终止时,shell就认为该命令已经执行完毕,这样子进程就自动在后台运行。第二、子进程继承了父进程的进程组ID,而且它有自己的进程ID,这就保证子进程不是一个进程组的组长进程,这是接下去调用setsid函数的必要条件。

(2) 调用setsid创建一个新会话

    步骤1中的子进程继承了父进程的进程组、会话、控制终端,调用setsid函数会创建新的会话、新的进程组,而且没有控制终端。

(3) 忽略SIGHUP信号并再次fork

    步骤2中的子进程是一个会话首进程,当没有控制终端的会话首进程打开一个终端设备时,该终端自动成为这个会话首进程的控制终端。再次fork可以确保新的子进程不再是一个会话首进程,从而不能自动获得一个控制终端。这里必须忽略SIGHUP信号,因为当会话首进程终止时,其会话中的所有进程(包括再次fork产生的子进程)都会受到SIGHUP信号。

(4) 将当前工作目录更改为根目录

(5) 重设文件权限掩码

(6) 关闭所有打开的文件描述符 

 

 

 

参考文章:

Linux进程关系

Linux守护进程