UNIX环境高级编程——守护进程

13.1 引言

守护进程(daemon)是生存期长的一种进程。它们常常在系统引导装入时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是在后台运行的。

13.2 守护进程的特征

系统进程依赖于操作系统实现。父进程ID为0的各进程通常是内核进程,它们作为系统引导装入过程的一部分而启动。(init是个例外,它是一个由内核在引导装入时启动的用户层次的命令)内核进程是特殊的,通常存在于系统的整个生命期中。它们以超级用户特权运行,无控制终端,无命令行。

进程1通常是init,它是一个系统守护进程,除了其他工作外,主要负责启动各运行层次特定的系统服务。

13.3 编程规则

  • 调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0);
  • 调用fork,然后使父进程exit
  • 调用setsid创建一个新会话;
  • 将当前工作目录更改为根目录;
  • 关闭不再需要的文件描述符;
  • 某些守护进程打开/dev/null使其具有文件描述符012,这样,任何一个试图读标准输入、写标准输出或标准错误的库例程都不会产生任何效果。

13.4 出错记录

syslog设施是一个集中的守护进程出错记录设施。
在这里插入图片描述
有以下3种产生日志消息的方法:
(1)内核例程可以调用log函数。任何一个用户进程都可以通过打开(open)并读取(read)/dev/klog设备来读取这些消息;
(2)大多数用户进程(守护进程)调用syslog函数来产生日志消息;
(3)无论一个用户进程是在此主机上,还是在通过TCP/IP网络连接到此主机的其他主机上,都可将日志消息发向UDP端口514

该设施的接口时syslog函数:

#include <syslog.h>

void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
int setlogmask(int maskpri);
										// 返回值:前日志记录优先级屏蔽字值
  • 调用openlog是可选择的,如果不调用openlog,则在第一次调用syslog时,自动调用openlog
  • 调用closelog也是可选择的,因为它只是关闭曾被用于与syslogd守护进程进行通信的描述符;
  • 调用openlog可以指定一个ident,此后,此ident将被加至每则日志消息中,ident一般是程序的名称;option参数是指定各种选项的位屏蔽,可用值如下:
    在这里插入图片描述
  • openlogfacility参数值取自下图,设置facility参数的目的是可以让配置文件说明,来自不同设施的消息将以不同的方式进行处理;如果不调用openlog,或者以facility0来调用它,那么在调用syslog时,可将facility作为priority参数的一个部分进行说明;
    在这里插入图片描述
  • 调用syslog产生一个日志消息,其priority参数是facilitylevel的组合,它们可选取的值分别列于facility(图13-4)和level(图13-5)中,level值的优先级从最高到最低依次排列;
    在这里插入图片描述
  • format参数以及其他所有参数传至vsprintf函数以便进行格式化。在format中,每个出现的%m字符都先被代换成与errno值对应的出错消息字符串(strerror);
  • setlogmask函数用于设置进程的记录优先级屏蔽字,它返回调用它之前的屏蔽字。

除了syslog,很多平台还提供它的一种变体来处理可变参数列表

#include <syslog.h>
#include <stdarg.h>

void vsyslog(int priority, const char *format, va_list arg);

13.5 单实例守护进程

  • 文件和记录锁机制保证一个守护进程只有一个副本在运行;
  • 如果每一个守护进程创建一个有固定名字的文件,并在该文件的整体上加一把写锁,那么只允许创建一把这样的写锁;
  • 如果守护进程在一个文件的整体上得到一把写锁,那么在该守护进程终止时,这把锁将被自动删除。

13.6 守护进程的惯例

  • 若守护进程使用锁文件,那么该文件通常存储在/var/run目录中,锁文件的名字通常是name.pid,其中,name是该守护进程或服务的名字;
  • 若守护进程支持配置选项,那么配置文件通常存放在/etc目录中,配置文件的名字通常是name.conf,其中,name是该守护进程或服务的名字;
  • 守护进程可用命令行启动,但通常它们是由系统初始化脚本之一(/etc/rc*/etc/init.d/*)启动的,如果在守护进程终止时,应当自动地重新启动它;
  • 若一个守护进程有一个配置文件,那么当该守护进程启动时会读该文件,但在此之后一般就不会再查看它,如果配置文件被修改,需要重启守护进程,使配置文件更改生效。

13.7 客户进程-服务器进程模型

  • 守护进程常常用作服务器进程;
  • 一般而言,服务器进程等待客户进程与其联系,提出某种类型的服务请求;
  • 客户进程向服务器进程发送请求,服务器进程则向客户进程回送应答。

13.8 实例代码

chapter13

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MinBadGuy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值