守护进程概述
守护进程,又叫daemon进程(不知怎的,我突然想起来吸血鬼日记中的达蒙了,很好 看的美剧),是Linux中的后台服务进程。他是一个生存期较长的进程,通常独立于控制终端并且周期性地执行 某种任务或者等待处理某些发生的事件。守护进程常常在系统引导载入时启动,在系统关闭时终止。Linux有 很多系统哦服务,大多数服务都是通过守护进程实现的。同时,守护进程还能完成许多系统任务,例如,作业 规划进程cronf、打印进程lqd等(这里的结尾字母 d 就是 daemon的意思)。
在Linux中,每一个系统 与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端称为这些进 程的控制终端,当控制终端关闭时,相应的进程都会自动关闭。但是守护进程却能够突破这种限制,它从被执 行开始运转,直到接收到某种信号或者整个系统关闭时才退出。如果想让某个进程不因为用户、终端或者其它 的变化而受到影响,那么就必须把这个进程变成一个守护进程。可见,守护进程是非常重要的。
编写 守护进程步骤
编写守护进程遵循一个特定的流程,下面就说一下守护进程的创建步骤。
1、创 建子进程,父进程退出。
这是编写守护进程的第一步。由于守护进程是脱离控制终端的,因此,完成 第一步后就会在shell终端造成一种程序已经运行完毕的假象,之后的所有工作都在子进程中完成,而用户在 shell终端则可以执行其他的命令,从而在形式上做到与控制终端的脱离。
但是,父进程创建了子进程 后退出,此时该子进程不就没有父进程了吗?守护进程中确实会出现这么一个有趣的现象:由于父进程已经先 于子进程退出,就会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进 程时,就会自动由1号进程(也就是 init 进程)收养它,这样原先的子进程就会变成 init 进程的子进程。其 关键代码如下;
2、在子进程中创建新会话
这个步骤是创建守护进程最重要的一步,虽然实现非常简单,但意义却非常重大。在这里使用 的是系统函数 setsid(),在具体介绍 setsid()之前,先了解以下两个概念:进程组和会话期。
进程 组。进程组是一个或多个进程的集合。进程组由进程组ID来唯一标识。除了进程号PID之外,进程组ID也是一 个进程的必备属性。每隔进程组都有一个组长进程,其组长进程的进程号PID等于进程组ID,且该进程组ID不 会因为组长进程的退出而受到影响。(组长没了,再找个组员来担任组长呗)
会话期。会话组是一个或 多个进程组的集合。通常,一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属 于这个会话期。进程组和会话期之间的关系如图1所示:
接下来具体介绍 setsid()的相关内 容。
① setsid()函数的作用。setsid()函数用于创建一个新的会话组,并让执行此函数的进程担任该 会话组的组长。调用setsid()有以下3个作用:
让进程摆脱原会话的控制
让进程摆脱原进程 组的控制
让进程摆脱原控制终端的控制
那么,回过头来想想,在创建守护进程时为什么要调 用 setsid()函数呢?是这样的,在创建守护进程的第一步中,调用了fork()函数创建子进程再令父进程退出 。由于在调用 fork()函数时,子进程全盘复制了父进程的会话期、进程组和控制终端等,虽然父进程退出了 ,但原先的会话期、进程组和控制终端等并没有改变,因此,还不是真正意义上的独立。而setsid()函数能够 使进程完全独立出来,从而脱离所有其他进程的控制。
② setsid函数格式