何为守护进程?
守护进程是一种在后台执行,而不由用户直接交互的电脑程序。此类程序会被以进程的形式初始化。守护进程程序的名字通常以字母 d 结尾,以指明这个进程实际是守护进程,如:syslogd,sshd 等。
编程原则?
创建守护进程分为以下几个步骤:
- 首先要做的就是调用 umask 函数,将文件模式创建屏蔽字设置为一个已知的值(通常为 0)。因为继承得来的文件模式创建屏蔽字可能会被设置为拒绝某些权限。如果守护进程要创建文件,那么它可能要设置特定的权限。例如:若守护进程要创建组可读、组可写的文件,继承的文件模式创建屏蔽字可能会屏蔽上述两种权限中的一种,而使其无法发挥作用。
另一方面,如果守护进程调用库函数创建文件,那么将文件模式创建屏蔽字设置为一个限制性更强的值(如 007)可能会更明智,因为库函数可能不允许调用者通过一个显示的函数参数来设置权限。 - 调用 fork,然后使父进程 exit。这样做实现了以下几点:第一,如果该守护进程是作为一条简单的 shell 命令启动的,那么父进程终止会让 shell 认为这条命令已经执行完毕。第二,虽然子进程继承了父进程的进程组 ID,但获得了一个新的进程 ID,这就使得子进程不是一个进程组的组长进程。这是下面 setsid 调用的先决条件。
- 调用 setsid 创建一个新会话。这样使调用进程:a) 成为新会话的首进程,b) 成为一个新进程组的组长进程,c) 没有控制终端。
在基于 System V 的系统中,有人建议在此时再次调用 fork,终止父进程,继续使用子进程中的守护进程。这就保证了该守护进程不是会话首进程,于是按照 System V 规则,可以防止它取得控制终端。为了避免取得控制终端的另一种方法是,打开一个终端设备时指定 O_NOCTTY。
- 将当前工作目录更改为根目录。从父进程继承来的当前目录可能在一个挂载的文件系统中。因为守护进程通常在系统再引导之前一直都存在,所以该文件系统将不能被卸载。
- 关闭不再需要的文件描述符。这使守护进程不再持有从父进程继承来的任何描述符(可以通过 open_max() 函数或 getrlimit() 函数获取拥有的最高文件描述符值,并关闭直到该值的所有描述符)。
- 某些守护进程打开 /dev/null 使其具有文件描述符 0、1 和 2。但是任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果。因为守护进程并不雨终端设备相关联,所以其输出无处显示,也无处从交互式用户那里接收输入。即使守护进程是从交互式会话启动的,但是守护进程是在后台运行的,所以登录会话的终止并不影响守护进程。如果其他用户在同一终端设备上登录,我们不希望在终端设备上见到守护进程的输出,用户也不希望他们在终端上的输入被守护进程读取。
Let’s begin
1 |
|
参考
- 【UNIX 环境高级编程】