【Linux】守护进程

来源:互联网 发布:算法工程师发展前景 编辑:程序博客网 时间:2024/05/22 05:06

守护进程daemon,是生存期较长的一种进程,名字一般以字母d结尾。它们常常在系统自举时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是在后台运行的。Linux系统有很多守护进程,它们执行日常事务活动。

1、系统自举

自举(bootstrapping)一词来自于人都是靠自身的“自举”机构站立起来的这一思想。计算机必须具备自举能力将自己所有的元件激活,以便能完成加载操作系统这一目的,然后再由操作系统承担起那些单靠自举代码无法完成的更复杂的任务。

自举只有两个功能:加电自检和磁盘引导。

加电自检:当我们按下计算机电源开关时,头几秒钟机器似乎什么反应也没有,其实,这时的计算机正在进行加电自检,以断定它的所有元件都在正确地工作。如果某个元件有故障,显示器上就会出现报警提示信息(如果显示器也不能正常工作,则以一串嘟嘟声来报警)。由于大多数计算机工作非常可靠,加电自检报警非常罕见。

磁盘引导:查找装有操作系统的磁盘驱动器。从磁盘加载操作系统的原因有二,一是操作系统升级简单容易,二是使用户拥有选择操作系统的自由。

当加电自检和磁盘引导完成时,自举操作就启动一个读写操作系统文件和将它们复制到随机存储器中的过程,此时的机器才是真正意义上的计算机。计算机的启动可以有冷启动和热启动两种方式 ,它们之间的差别是热启动不进行机器的自检(机器本身配置的检查与测试),当计算机在使用过程中由于某些原因造成死机时,可以对计算机进行热启动处理。

2、守护进程的概念

ps命令可打印系统中各个进程的状态,该命令有多个选项,有关细节可通过man查看。下面在Ubuntu下执行ps命令:

$ps axj

选项-a显示由其他用户所拥有的进程的状态,-x显示没有控制终端的进程状态,-j显示与作业有关的信息。ps的输出大致是:

 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND    0     1     1     1 ?           -1 Ss       0   0:00 /sbin/init    0     2     0     0 ?           -1 S        0   0:33 [kthreadd]    2     3     0     0 ?           -1 S        0   1:28 [ksoftirqd/0]    2     5     0     0 ?           -1 S<       0   0:00 [kworker/0:0H]    2     7     0     0 ?           -1 S<       0   0:00 [kworker/u:0H]    2     8     0     0 ?           -1 S        0   0:01 [migration/0]    2     9     0     0 ?           -1 S        0   0:00 [rcu_bh]    2    10     0     0 ?           -1 S        0   7:12 [rcu_sched]

按照顺序,各列标题的意义是:父进程ID、进程ID、进程组ID、会话ID、终端名称、终端进程组ID、进程状态、用户ID、TIME以及命令字符串。父进程ID为0的各进程通常是内核进程,它们作为系统自举过程的一部分而启动,init是此种进程的例外,它是系统在自举时启动的用户层命令。内核进程是特殊的,通常存在与系统的整个生命期中,它们以超级用户特权运行,无控制终端,无命令行。大多数守护进程都以超级用户特权运行,UID为0,没有一个守护进程具有控制终端,其终端名TTY设置为问号,终端前台进程组ID设置为-1,内核守护进程以无控制终端方式启动,用户层守护进程缺少控制终端可能是守护进程调用了setsid的结果,所有用户层守护进程都是进程组的组长进程以及会话的首进程,而且是这些进程组和会话中的唯一进程。

3、编写守护进程

在编写守护进程程序时,需遵循一些基本规则:

(1)首先要做的是调用umask将文件模式创建屏蔽字设置为0,因为有继承得来的文件模式创建屏蔽字可能会拒绝设置某些权限。
(2)调用fork,然后使父进程退出。如果该守护进程由shell命令启动,父进程退出则认为shell命令执行完毕。子进程继承了父进程的进程组ID,但不是进程组的组长进程。
(3)调用setsid以创建一个新会话,使得调用进程成为新会话的首进程,成为新进程组的组长进程,没有控制终端。
(4)将当前工作目录更改为根目录。
(5)关闭不再需要的文件描述符。
(6)某些守护进程打开/dev/null使其具有文件描述符0、1和2,任何一个试图读标准输入、写标准输出或标准出错的库例程都不会产生任何效果。因为守护进程并不与终端设备相关联,所以不能在终端设备上显示输出,也不能从交互式用户那里接收输入。

与守护进程有关的一个问题是如何处理出错消息,因为它没有控制终端,所以不能只是简单地写到标准出错上,需要有一个集中的守护进程出错记录设施,如syslogd守护进程,在“/etc/services”文件中可看到syslog的端口号为514,使用udp传输协议。log处理相关函数如下:

#include <syslog.h>void openlog(const char *ident, int option, int facility);void syslog(int priority, const char *format, ...);void closelog(void);void vsyslog(int priority, const char *format, va_list ap);

4、守护进程惯例

为了正常运作,某些守护进程实现为单实例的,也就是在任一时刻只运行该守护进程的一个副本。文件锁和记录锁机制是一种方法,该方法用来保证一个守护进程只有一个副本在运行。在Linux系统中,守护进程遵循下列公共惯例:

(1)若守护进程使用锁文件,那么该文件通常存放在/var/run目录中。锁文件的名字通常是name.pid,name是该守护进程或服务的名字。
(2)若守护进程支持配置选项,那么配置文件通常存放在/etc目录中。配置文件的名字通常是name.conf。
(3)守护进程可用命令行启动,但通常它们是由系统初始化脚本启动的,如“/ect/rc*”、“/etc/init.d/*”。
(4)若一守护进程有一配置文件,那么当该守护进程启动时,它读该文件,但在此之后一般就不会再查看它。

1 0