13 - 守护进程
GitHub 地址git
1. 守护进程
守护进程 (daemoon) 是生存期长的一种进程。经常在系统引导装入时启动,仅在系统关闭时才终止。它们是在后台运行的,没有控制终端。UNIX 有不少守护进程,它们执行 平常事务活动 。github
2. 守护进程的特征
内核进程:父进程 ID 为 \(0\) 的各进程一般是内核进程,它们做为系统引导装入的一部分而启动 。shell
内核守护进程:对于须要在进程上下文执行工做但却不被用户层进程上下文调用的每个内核组件,一般有它的内核守护进程 。编程
init 进程:是一个 系统守护进程 ,主要负责启动各运行层次特定的系统服务 。spa
用户层守护进程:init 进程启动的系统服务一般是在它们本身拥有的守护进程的帮助下实现的,用户层守护进程的父进程是 init 进程 。code
守护进程的特征:继承
- 大多数守护进程都是以超级用户( root )特权运行
- 全部守护进程都没有控制终端,其控制终端名设置为问号
- 内核守护进程以无控制终端方式启动
- 用户层守护进程缺乏控制终端多是守护进程调用了 setsid 的结果
- 大多数用户层守护进程都是进程组的组长进程以及会话的首进程,并且是这些进程组和会话中的惟一进程
3. 编程规则
编写守护进程程序需遵循一些 基本规则:进程
- 调用 umask 将文件模式建立屏蔽字设置为一个已知值(一般是 \(0\) )。由于由继承得来的文件模式建立屏蔽字可能会被设置为拒绝某些权限,而若是守护进程要建立文件,那么它可能要设置特定的权限 。
- 调用 fork ,而后使父进程 exit 。这样作有两个缘由:
- 若是该守护进程是做为一条 shell 命令启动的,那么父进程终止会让 shell 认为这条命令已经执行完毕,shell 能够执行其余命令,形式上作到了守护进程与终端控制的脱离
- 子进程继承了父进程进程组 ID ,但得到了新的进程 ID,这就保证了子进程不是一个进程组的组长进程(使用 setsid 的先决条件 )
- 调用 setsid 建立一个新会话 。使调用进程:成为新会话首进程、成为一个新进程组的组长进程、没有控制终端。( 在此可再次调用 fork ,终止父进程,继续使用子进程中的守护进程,保证该守护进程不是会话首进程。 )
- 将当前工做目录更改成根目录。由于从父进程继承过来的当前工做目录可能在一个挂载的文件系统中,守护进程随系统存在的特性使得此文件系统不能被卸载。也能够将当前工做目录更改到某个指定位置。
- 关闭文件描述符。
- 某些守护进程打开
/dev/null
使其具备文件描述符 \(0\) 、\(1\) 和 \(2\) ,这样任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果。(由于守护进程并不与终端设备相关联)
4. 单实例守护进程
为了正常运做,某些守护进程会实现为:在任一时刻只运行该守护进程的一个副本。例如,这种守护进程可能须要排他地访问一个设备 。事务
文件和记录锁 机制为一种方法提供了基础,该方法保证一个守护进程只有一个副本在运行 。若是一个守护进程建立一个有固定名字的文件,并在该文件的总体上加一把写锁,那么只容许建立一把这样的写锁,在此以后建立写锁的尝试都会失败,这向后续守护进程副本指明已有一个副本在运行 。get