您的位置:首页 > 运维架构 > Linux

Linux系统的守护进程(Daemon Process)

2018-02-23 09:48 260 查看
这篇文章介绍守护进程的概念, 结构, 编写守护进程以及报告进程错误状况. 1. 概念:守护进程又称为精灵进程(daemon), 是生存时间比较长的一种进程. 它们常常在系统自举时启动, 仅在系统关闭时才终止. 因为它们没有控制终端, 所以说它们是在后台运行的. 先来介绍一些Linux系统常见的守护进程:init: 它的pid为1, 是系统守护进程, 负责启动系统服务, 这些服务通常自己也拥有守护进程.
keventd: 为在内核中运行计划执行的函数提供进程上下文.
kapmd: 对计算机系统中具有的高级电源管理提供支持.
kswapd: 页面调出守护进程(Pageout Daemon), 它通过将脏页面(Dirty Page)以低速写到磁盘上, 使这些页面在需要时仍然可以回收使用, 这种方式支持虚存子系统.
bdflush: 当可用内存达到下限时, 将脏缓冲区从缓冲池中冲洗到磁盘上.
kupdated: 将脏页面冲洗到磁盘上.
portmap: 提供将RPC(Remote Procedure Call, 远程过程调用)程序号映射到网络端口号的服务.
syslogd: 提供把系统消息记入日志的接口, 供需要的程序使用. 可以打印到termino也可以写到文件.
inetd: 侦听系统网络接口, 以便取得来自网络的各种网络服务请求.
crond: 在指定的日期和时间执行指定的命令. 使定期地执行相关程序得意实现.
cupsd: 打印假脱机进程, 它处理对系统提出的所有打印请求.
nfsd, lockd, rpciod: 提供对网络文件系统的支持(Network File System).
 2. 编程规则:首先要调用umask将文件模式创建屏蔽字设置为0.
调用fork, 然后使父进程退出. 这样做为了实现下面几点:如果该守护进程是作为一条简单shell命令启动的, 那么父进程终止使得shell认为这条命令已经执行完毕.
子进程继承了父进程的进程组ID, 但具有一个新的进程ID, 这就保证了子进程不是一个进程组的组长进程. 这对于第三步的setsid调用是不要的前提.

调用setsid以创建一个新会话, 使得调用进程:成为新会话的首进程.
成为一个新进程组的组长进程.
没有控制终端.

将当前工作目录更改为根目录. 这是为了防止当前工作目录在mount的文件系统中.
关闭不再需要的文件描述符.
某些守护进程打开/dev/null适其具有filedes 0 1 2, 使标准输入, 输出, 出错的例程都不会产生任何效果.
 3. 出错记录:守护进程是没有控制终端的, 所以不能用简单的perror实现错误报告. 在Linux中, 有一个集中的守护进程出错记录设施, 它就是syslog.有3种方法产生日志消息:内核例程可以调用log函数. 任何一个用户进程通过读取/dev/klog就可以获得这些信息, 当然你要先打开这个设备.
大多数用户进程(守护进程)调用syslog函数产生日志消息.这使消息发送至UNIX域UDP Socket: /dev/log.
在此主机上的一个用户进程, 或通过TCP/IP网络连接到此主机上的一个用户进程可将日志消息发向UDP端口514.注意, syslog并不产生这些UDP数据报, 而是要求产生此日志消息的进程进行显示的网络编程.

下面看一下syslog的函数:头文件: <syslog.h>
原型:void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog();
int setlogmask(int maskpri);

返回值: 前日志记录优先级屏蔽值.
说明:openlog调用是可选择的, 如不调用, 在第一次调用syslog时会自动调用openlog
closelog调用也是可选择的, 它只关闭曾用于与syslogd守护进程通信的描述符.

参数:ident: log会把它加到每则日志消息中, 它一般是程序的名称(如inetd).
option: 指定位屏蔽选项.LOG_CONS: 若日志消息不能通过UNIX域数据报送至syslogd, 则该消息写至控制台.
LOG_NDELAY: 立即打开至syslogd的UNIX域数据报socket, 而不等记录第一条消息.
LOG_NOWAIT: 不等待在将消息记入日志过程中可能创建的子进程. 阻塞了与捕捉SIGCHLD信号的应用程序冲突.
LOG_ODELAY: 在记录第一条消息之前延迟打开至syslogd的连接.
LOG_PERROR: 除了将日志消息发送给syslogd外, 还将它写到标准出错.
LOG_PID: 每条消息都包含进程ID.

facility: 让配置文件说明, 来自不同设施的消息将以不同的方式进程处理.LOG_AUTH: 授权程序: login, su, getty等.
LOG_AUTHPRIV: 与LOG_AUTH相同, 但写日志文件时具有权限限制.
LOG_CRON: cron和at.
LOG_DAEMON: 系统守护进程: inetd, routed等.
LOG_FTP: FTP守护进程(ftpd).
LOG_KERN: 内核产生的消息.
LOG_LOCAL0-9: 保留由本地使用.
LOG_LPR: 行打印系统: lpd, lpc等.
LOG_MAIL: 邮件系统.
LOG_NEWS: Usenet网络新闻系统.
LOG_SYSLOG: syslogd守护进程.
LOG_USER: 来自其他用户进程的消息(默认).
LOG_UUCP: UUCP系统.

priority: 这个参数是facility和level的组合, 可以是(由高到低):LOG_EMERG: 紧急状态(系统不可使用).
LOG_ALERT: 必须立即修复的状态.
LOG_CRIT: 严重状态.
LOG_ERR: 出错状态.
LOG_WARNING: 警告状态.
LOG_NOTICE: 正常, 但重要的状态.
LOG_INFO: 信息性消息.
LOG_DEBUG: 调试消息.

此外还有一个变体函数:#include <syslog.h>
#include <stdarg.h>
void vsyslog(int priority, const char *format, va_list arg);
 4. 简单实例:openlog("lpd", LOG_PID, LOG_LPR);syslog(LOG_ERR, "open error for %s: %m", filename);等同于:syslog(LOG_ERR | LOG_LPR, "open error for %s: %m", filename);不过更推荐用第一种方式, 有open有close, 更规矩更清晰.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: