8.14 进程会计
2012-10-22Unix环境高级编程-进程控制
8.14 进程会计
很多UNIX系统提供了一个选择项以进行进程会计事务处理。当取了这种选择项后,每当进程结束时内核就写一个会计记录。典型的会计记录是3 2字节长的二进制数据,包括命令名、所使用的CPU时间总量、用户ID和组ID、起动时间等。本节将比较译细地说明这种会计记录,这样也使我们得到了一个再次观察进程的机会,得到了使用5 . 9节中所介绍的fread函数的机会。
一个至今没有说明过的函数( acct )起动和终止进程会计。唯一使用这一函数的是accton ( 8 )命令。超级用户执行一个带路径名参数的accton命令起动会计处理。该路径名通常是/ v a r / a d m / p acct(早期系统中为/ u s r / a d m / acct)。执行不带任何参数的accton命令则停止会计处理。
会计记录结构定义在头文件<sys/acct.h>中,其样式如下:
typedef u_short comp_t; /* 3-bit base 8 exponent; 13-bit fraction */
struct acct
{
char ac_flag; /* flag (see Figure 8.26) */
char ac_stat; /* termination status (signal & core flag only) */
/* (Solaris only) */
uid_t ac_uid; /* real user ID */
gid_t ac_gid; /* real group ID */
dev_t ac_tty; /* controlling terminal */
time_t ac_btime; /* starting calendar time */
comp_t ac_utime; /* user CPU time (clock ticks) */
comp_t ac_stime; /* system CPU time (clock ticks) */
comp_t ac_etime; /* elapsed time (clock ticks) */
comp_t ac_mem; /* average memory usage */
comp_t ac_io; /* bytes transferred (by read and write) */
/* "blocks" on BSD systems */
comp_t ac_rw; /* blocks read or written */
/* (not present on BSD systems) */
char ac_comm[8]; /* command name: [8] for Solaris, */
/* [10] for Mac OS X, [16] for FreeBSD, and */
/* [17] for Linux */
};
会计记录所需的各个数据(各CPU时间、传输的字符数等)都由内核保存在进程表中,并在一个新进程被创建时置初值(例如fork之后在子进程中)。进程终止时写一个会计记录。这就意味着在会计文件中记录的顺序对应于进程终止的顺序,而不是它们起动的顺序。为了确定起动顺序,需要读全部会计文件,并按起动日历时间进行排序。这不是一种很完善的方法,因为日历时间的单位是秒(见1 . 1 0节),在一个给定的秒中可能起动了多个进程。而墙上时钟时间的单位是时钟滴答(通常,每秒滴答数在5 0~1 0 0之间)。但是我们并不知道进程的终止时间,所知道的只是起动时间和终止顺序。这就意味着,即使墙上时间比起动时间要精确得多,但是仍不能按照会计文件中的数据重构各进程的精确起动顺序。
会计记录对应于进程而不是程序。在fork之后,内核为子进程初始化一个记录,而不是在一个新程序被执行时。虽然exec并不创建一个新的会计记录,但相应记录中的命令名改变了,AFORK标志则被清除。这意味着,如果一个进程顺序执行了三个程序(A exec B,B exec C,最后C exit),但只写一个会计记录。在该记录中的命令名对应于程序C,但CPU时间是程序A、B、C之和。