1、守护进程的特征
守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,仅在系统关闭时终止。因为它们没有控制终端,所以说它们是在后台运行的。
父进程ID为0的各进程通常是内核进程,它们作为系统引导装入过程的一部分而启动(init(进程1)是个例外,它是一个由内核在引导装入时启动的用户层次的命令)。
对于需要在进程上下文执行工作但却不被用户层进程上下文调用的每一个内核组件,通常有它自己的内核守护进程。
大多数用户层守护进程都是进程组的组长进程以及会话的首进程,而且是这些进程组和会话的唯一进程。
2、编程规则
在编写守护进程程序时需遵循一些基本规则,以防止产生不必要的交互作用。
(1)首先要做的是调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0)。
(2)调用fork,然后使父进程exit。
(3)调用setsid创建一个新会话。
(4)将当前工作目录更改为根目录。
(5)关闭不再需要的文件描述符。这使守护进程不再持有从其父进程继承来的任何文件描述符。
(6)某些守护进程打开、dev/null使其具有文件描述符0、1和2,这样,任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果。
3、出错记录
有以下3种产生日志消息的方法:
(1)内核例程可以调用log函数。任何一个用户进程都可以通过打开并读取/dev/klog设备来读取这些信息。
(2)大多数用户进程(守护进程)调用syslog函数来产生日志消息。
(3)无论一个用户进程是在此主机上,还是在通过TCP/IP网络连接到此主机的其他主机上,都可将日志消息发向UDP端口514。
通常,syslogd守护进程读取所有3中格式的日志消息。此守护进程在启动时读一个配置文件,其文件名一般为/etc/syslog.conf,该文件决定了不同种类的消息应送向何处。
#include <syslog.h>
void openlog(const char *ident,int option,int facility);//可选择,ident一般是程序的名字
void syslog(int priority,const char *format,...);
void closelog(void);//可选择
int setlogmask(int maskpri);//用于设置进程的记录优先级屏蔽字。返回前日志记录优先级屏蔽字值。
设置facility参数的目的是可以让配置文件说明,来自不同设施的消息将以不同的方式处理。如果不调用openlog,或者以facility为0来调用它,那么在调用syslog时,可将facility作为priority参数的一个部分进行说明。
调用syslog产生一个日志消息。其priority参数是facility和level的组合。
4、单实例守护进程
为了正常运作,某些守护进程会实现为,在任一时刻值运行该守护进程的一个副本。
文件和记录锁机制:如果每一个守护进程创建一个有固定名字的文件,并在该文件的整体上加一把写锁,那么只允许创建一把这样的写锁。如果守护进程在一个文件的整体上得到一把写锁,那么在该守护进程终止时,这把锁将被自动删除。
5、守护进程的惯例
- 若守护进程使用锁文件,那么该文件通常存储在/var/run目录中。需要注意的是,守护进程可能需要具有超级用户特权才能在此目录下创建文件。
- 若守护进程支持配置选项,那么配置文件通常放在/etc目录中。
- 守护进程可用命令行启动,但通常它们是由系统初始化脚本之一(/etc/rc8或/etc/init.d/*)启动的。
- 若一个守护进程有一个配置文件,那么当该守护进程启动时会读该文件。若某个管理员更改了配置文件,那么该守护进程可能需要被停止,然后再启动,以使配置文件的更改生效。为避免此种麻烦,某些守护进程将捕捉SIGHUP信号,当它们接收到该信号时,重新读配置文件。