UNIX环境高级编程 守护进程

 

 

 

相关函数列表

//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);

//除syslog,很多平台还提供它的一种变体来处理可变参数列表
#include <syslog.h>
#include <stdarg.h>
void vsyslog(int priority, const char *format, va_list arg);

 

 

ps -efj

结构如下

UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root         1     0     1     1  0 Aug07 ?        00:00:01 /sbin/init
root         2     0     0     0  0 Aug07 ?        00:00:00 [kthreadd]
root         3     2     0     0  0 Aug07 ?        00:00:00 [migration/0]
root         4     2     0     0  0 Aug07 ?        00:00:02 [ksoftirqd/0]
root         5     2     0     0  0 Aug07 ?        00:00:00 [migration/0]
root         6     2     0     0  0 Aug07 ?        00:00:10 [watchdog/0]
root         7     2     0     0  0 Aug07 ?        00:03:41 [events/0]
root         8     2     0     0  0 Aug07 ?        00:00:00 [cgroup]
root         9     2     0     0  0 Aug07 ?        00:00:00 [khelper]
root        10     2     0     0  0 Aug07 ?        00:00:00 [netns]
root        11     2     0     0  0 Aug07 ?        00:00:00 [async/mgr]
root        12     2     0     0  0 Aug07 ?        00:00:00 [pm]
root        13     2     0     0  0 Aug07 ?        00:00:18 [sync_supers]
root        14     2     0     0  0 Aug07 ?        00:00:20 [bdi-default]
root        15     2     0     0  0 Aug07 ?        00:00:00 [kintegrityd/0]
root        16     2     0     0  0 Aug07 ?        00:00:01 [kblockd/0]
root        17     2     0     0  0 Aug07 ?        00:00:00 [kacpid]
root        18     2     0     0  0 Aug07 ?        00:00:00 [kacpi_notify]
root        19     2     0     0  0 Aug07 ?        00:00:00 [kacpi_hotplug]
root        20     2     0     0  0 Aug07 ?        00:00:00 [ata/0]
root        21     2     0     0  0 Aug07 ?        00:00:00 [ata_aux]
root        22     2     0     0  0 Aug07 ?        00:00:00 [ksuspend_usbd]
root        23     2     0     0  0 Aug07 ?        00:00:00 [khubd]
root        24     2     0     0  0 Aug07 ?        00:00:00 [kseriod]
root        25     2     0     0  0 Aug07 ?        00:00:00 [md/0]
root        26     2     0     0  0 Aug07 ?        00:00:00 [md_misc/0]
root        27     2     0     0  0 Aug07 ?        00:00:01 [khungtaskd]
root        28     2     0     0  0 Aug07 ?        00:00:00 [kswapd0]
root        29     2     0     0  0 Aug07 ?        00:00:00 [ksmd]
root        30     2     0     0  0 Aug07 ?        00:00:00 [khugepaged]
root        31     2     0     0  0 Aug07 ?        00:00:00 [aio/0]
root        32     2     0     0  0 Aug07 ?        00:00:00 [crypto/0]
root        37     2     0     0  0 Aug07 ?        00:00:00 [kthrotld/0]
root        39     2     0     0  0 Aug07 ?        00:00:00 [kpsmoused]
root        40     2     0     0  0 Aug07 ?        00:00:00 [usbhid_resumer]
root        70     2     0     0  0 Aug07 ?        00:00:00 [kstriped]
root       275     2     0     0  0 Aug07 ?        00:00:00 [scsi_eh_0]
root       276     2     0     0  0 Aug07 ?        00:00:00 [scsi_eh_1]
root       359     2     0     0  0 Aug07 ?        00:00:00 [virtio-blk]
root       380     2     0     0  0 Aug07 ?        00:00:00 [jbd2/vda1-8]
root       381     2     0     0  0 Aug07 ?        00:00:00 [ext4-dio-unwrit]
root       430     2     0     0  0 Aug07 ?        00:00:00 [kauditd]
root       709     2     0     0  0 Aug07 ?        00:00:00 [virtio-net]
root       839     2     0     0  0 Aug07 ?        00:00:00 [vballoon]
root       906     2     0     0  0 Aug07 ?        00:00:00 [kjournald]

以上分别是用户ID,进程ID,父进程ID,进程组ID,会话ID,终端名称以及命令字符串

 

 

Linux中的守护进程

1.kswapd守护进程也称为内存换页守护进程。它支持虚拟内存子系统在经过一段时间后将脏页面慢慢的写会

   磁盘来回收这些页面

2.flush守护进程再可用内存达到设置的最小阀值时将脏页面刷新到磁盘。它也定期的将脏页面刷新回磁盘来

   减少在系统出现故障时发生的数据丢失。多个刷新守护进程可以同时存在,每个写回设备都有一个刷新守护

   进程。输出实例中显示一个名为flush-8:0的刷新守护进程。从名字可以看出,写回设备室通过主设备号(8)和

   副设备号(0)来识别的

3.sync_supers守护进程定期将文件系统刷新到磁盘

4.jbd守护进程帮助实现了ext4文件系统中的日志功能

5.rpcbind守护进程提供将远程过程调用(Remote Procedure Call RPC)程序号映射为网络端口号的服务。

   syslogd守护进程可以被由管理员启动的将系统消息记入日志的任何程序使用。可以在一台实际的控制台上

   打印这些消息,也可以将他们写到一个文件中。

6.cron守护进程再定期安排的日期和时间执行命令。

 

 

编写守护进程时需要遵循一些基本规则,以防产生不必要的交互:

1)首先调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0),由继承的来的文件模式创建屏蔽字

   可能会被设置为拒绝某些权限。如果守护进程要创建文件,那么它可能要设置特定的权限。

2)调用fork,然后使父进程exit,这样做实现下面几点

    a)如果该守护进程是作为第一条简单的shell命令启动的,那么父进程终止会让shell认为这条命令已经执行

       完毕

     b)虽然子进程继承了父进程的进程组ID,但获得了一个新的进程ID,这样就保证了子进程不是一个进程组

        的组长进程,这是虾米要进行的setsid调用的先决条件

3)调用setsid建一个会话,然后

     a)使进程成为会话的首进程

     b)成为一个新进程进程组的组长进程

     c)没有控制终端

4)将当前工作目录更改为根目录。从父进程处继承过来的当前工作目录可能再一个挂载的文件系统中。因为

    守护进程通常在系统再引导之前是一直存在的,所以如果守护进程的当前工作目录在一个挂载文件系统

    中,那么该文件系统就不能被卸载。

5)关闭不在需要的文件描述符,这使得守护进程不再持有从父进程继承来的任何文件描述符(父进程可能是

    shell进程,或者其他某个进程)。可以使用open_max函数或getrlimit函数来判定最高文件描述符值,并

    关闭知道该值的所有描述符

6)某些守护进程打开/dev/null使其具有文件描述符0,1,2这样,任何一个试图读标准输入,写标准输出

   或标准错误的库例程都不会产生任何效果。因为守护进程并不与终端设备相关联

 

 

 

出错记录

守护进程调用syslog函数,将日志写入到一个集中式的地方

有以下三种产生日志消息的方法

1)内核例程可以调用log函数,任何一个用户进程都可以通过打开(open)并读取/dev/klog设备来读取这些

   消息

2)大多数用户进程(守护进程)调用syslog函数来产生日志消息,这使得消息发送至UNIX域数据报字段/dev/log

3)无论一个用户进程是在此主机上,还是通过TCP/IP网络连接到此主机的其他主机上,都可以将日志消息

   发向UDP端口514。syslog函数从不产生这些UDP数据报他们要求产生次消息日志的进程进行显示的网络

   编程

 

BSD的syslog设施

UNIX环境高级编程 守护进程
 

 

 

syslog的 openlog函数的option参数

option 说明
LOG_CONS 若日志消息不能通过UNXI域数据报发送至syslogd,则将消息写至控制台
LOG_NEDLAY

立即打开至syslogd守护进程的UNIX域数据报套接字,不要等到第一条消息已经被记录时

再打开。通常在记录第一条消息之前,不打开该套接字

LOG_NOWAIT

不要等待在将消息记入日志过程中可能已创建的子进程。因为再syslog调用wait时,应用

程序可能已获得了子进程的状态,这种处理阻止了与捕捉SIGCHLD信号的应用程序之间

产生的冲突

LOG_ODELAY 在第一条消息被记录之前延迟打开至syslogd守护进程的连接
LOG_PERROR 除将日志消息发送给syslogd外,还将它写至标准出错(在Solaris上不可用)
LOG_PID

记录每条消息都要包含进程ID,此选项可供对每个不同的请求都fork一个子进程的守护

进程使用(与从不调用fork的守护进程相比较,如syslogd)

 

openlog的facility参数

facility 说明
LOG_AUDIT 审计设施
LOG_AUTH 授权程序login,su,getty等
LOG_AUTHPRIV

与LOG_AUTH相同,但写日志文件时

具有权限限制

LOG_CONCOLE 将消息写入/dev/console
LOG_CRON cron和at
LOG_DAEMON 系统守护进程inetd,routed等
LOG_FTP FTP守护进程ftpd
LOG_KERN 内核产生消息
LOG_LOCAL0 保留由本地使用
LOG_LOCAL1 保留由本地使用
LOG_LOCAL2 保留由本地使用
LOG_LOCAL3 保留由本地使用
LOG_LOCAL4 保留由本地使用
LOG_LOCAL5 保留由本地使用
LOG_LOCAL6 保留由本地使用
LOG_LOCAL7 保留由本地使用
LOG_LPR 行式打印机系统lpd,lpc等
LOG_MAIL 邮件系统
LOG_NEWS Usenet网络新闻系统
LOG_NTP 网络时间协议系统
LOG_SECURITY 安全子系统
LOG_SYSLOG syslogd收紧进程本身
LOG_USER 来自掐用户进程的消息(默认)
LOG_UUCP UUCP系统

 

syslog中的level(按序排列)

level 说明
LOG_EMERG 紧急(系统不可使用)(最高优先级)
LOG_ALERT 必须立即修复的情况
LOG_CRIT 严重情况(如硬件设备处错)
LOG_ERR 出错情况
LOG_WARNING 警告情况
LOG_NOTICE 正常但重要的情况
LOG_INFO 信息性消息
LOG_DEBUG 调试消息(最低优先级)

 

 

 

守护进程遵循以下通用惯例:

1)若守护进程使用锁文件,那么该文件通常存储在/var/run目录中。锁文件的名字通常是name.pid,如cron.pid是

2)若守护进程支持配置选项,那么配置文件通常放在/etc/目录中。配置文件的名字通常是name.conf,其中

    name是该守护进程或服务的名字,如syslogd守护进程的配置文件通常是/etc/syslog.conf

3)守护进程可用命令行启动,但通常他们是系统初始化脚本之一(/etc/rc*或/etc/init.d/*)启动的。如果守护进程

   终止时,应当自动的重启动它,则我们可在/etc/inittab中为该守护进程包括respawn记录项,这样init就将

   重新启动该守护进程

4)若一个守护进程有一个配置文件,那么当该守护进程启动时会读该文件,但在此之后一般就不会再查看它。

   若更改了配置文件,那么守护进程应该重启。为避免这种麻烦,某些守护进程将捕捉SIGHUP信号,当他们

   接收到该信号时,重新读配置文件。因为守护进程并不与终端相结合,他们活是无控制终端的会话首进程,或

   是孤儿进程组中的成员,所以守护进程没有理由期望接收SIGHUP,守护进程可以安全的重复使用SIGHUP

 

 

 

 

 

参考

BSD syslog协议的格式

 

 

 

 

 

你可能感兴趣的:(unix)