`

进程会计

阅读更多
    大多数 UNIX 系统都提供了一个选项以进行进程会计处理。启用该选项后,每当进程结束时内核就会写一个会计记录。典型的会计记录包含总量较小的二进制数据,一般包括命令名、所使用的 CPU 时间总量、用户 ID 和组 ID、启动时间等。函数 acct 是用来启用和禁用进程会计,唯一使用这一函数的是 accton 命令。超级用户执行一个带路径名参数的 accton 命令启用会计处理。会计记录会写到指定的文件中,在 FreeBSD 和 Mac OS X 中,该文件通常是 /var/account/acct,Linux 中是 /var/account/pacct,Solaris 中是 /var/adm/pacct。执行不带任何参数的 accton 命令则停止会计处理。
    会计记录结构定义在头文件<sys/acct.h>中,虽然每种系统的实现各不相同,但会计记录样式基本如下:
#include <sys/acct.h>
typedef u_short comp_t;     // 3-bit base 8 exponent; 13-bit fraction
type acct{
	char	ac_flag;        // flag, see below
	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
	comp_t	ac_stime;       // system CPU time
	comp_t	ac_etime;       // elapsed time
	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
};

    其中 ac_flag 成员记录了进程在执行期间的如下事件。

    会计记录所需的各个数据(各 CPU 时间、传输的字符数等)都由内核保存在进程表中,并在一个新进程被创建时初始化。进程终止时写一个会计记录。这产生两个结果。
    (1)不能获取永远不终止的进程的会计记录,如 init 进程和内核守护进程等。
    (2)在会计文件中记录的顺序对应于进程终止的顺序,而不是它们启动的顺序。为了确定启动顺序,需要读取全部会计文件,然后按启动日历时间进行排序。
    会计记录对应于进程而不是程序。在 fork 之后,内核为子进程初始化一个记录,而不是在一个新程序被执行时初始化。虽然 exec 并不创建一个新的会计记录,但相应记录中的命令名改变了,AFORK 标志则被清除。这意味着,如果一个进程顺序执行了 3 个程序(A exec B、B exec C,最后是 C exit),只会写一个会计记录,在该记录中的命令名对应与 C,但 CPU 时间是 A、B 和 C 之和。
    下面这个程序 acctDemo 可用来生成会计数据。它按下图调用了 4 次 frok,每个子进程做不同的事情,然后终止。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

int main(void){
	pid_t	pid;

	if((pid=fork()) < 0){
		printf("fork 1 error\n");
	}else if(pid != 0){		// parent
		sleep(2);
		exit(2);			// terminate with exit status 2
	}

	if((pid=fork()) < 0){
		printf("fork 2 error\n");
	}else if(pid != 0){		// first child
		sleep(4);
		abort();			// terminate with core dump
	}

	if((pid=fork()) < 0){
		printf("fork 3 error\n");
	}else if(pid != 0){		// second child
		execl("/bin/dd", "if=/etc/passwd", "of=/dev/null", NULL);
		exit(7);			// shouldn't get here
	}

	if((pid=fork()) < 0){
		printf("fork 4 error\n");
	}else if(pid != 0){		// third child
		sleep(8);
		exit(0);			// normal exit
	}

	sleep(6);				// fourth child
	kill(getpid(), SIGKILL);	// terminate w/signal, no core dump
	exit(6);				// shouldn't get here
}

    然后可使用下面这个程序 printAcct 来打印运行上面程序后产生的会计数据。
#include <stdio.h>
#include <stdlib.h>
#include <sys/acct.h>

//#define BSD             // 如果是 BSD 系统就取消该行注释
//#define LINUX           // 如果是 Linux 系统就取消该行注释
//#define HAS_AC_STAT     // 如果 acct 结构有 ac_stat 这个成员就取消该行注释
//#define HAS_ACORE       // 如果 ac_flag 标记支持 ACORE 选项就取消该行注释
//#define HAS_AXSIG       // 如果 ac_flag 标记支持 AXSIG 选项就取消该行注释

#if defined(BSD)	// different structure in FreeBSD
	#define acct	acctv2
	#define ac_flag	ac_trailer.ac_flag
	#define FMT	"%-*.*s e = %.0f, chars = %.0f, %c %c %c %c\n"
#elif defined(HAS_AC_STAT)
	#define FMT	"%-*.*s e = %6ld, chars = %7ld, stat = %3u: %c %c %c %c\n"
#else
	#define FMT	"%-*.*s e = %6ld, chars = %7ld, %c %c %c %c\n"
#endif

#if defined(LINUX)
	#define acct	acct_v3		// different structure in Linux
#endif

#if !defined(HAS_ACORE)
	#define ACORE	0
#endif
#if !defined(HAS_AXSIG)
	#define AXSIG	0
#endif

#if !defined(BSD)
static unsigned long
compt2ulong(comp_t comptime){	// convert comp_t to unsigned long
	unsigned long	val;
	int	exp;

	val = comptime & 0x1fff;	// 13-bit fraction
	exp = (comptime >> 13) & 7;	// 3-bit exponent (0-7)
	while(exp-- > 0)
		val *= 8;
	return val;
}
#endif

int main(int argc, char *argv[]){
	struct acct	acdata;
	FILE	*fp;

	if(argc != 2){
		printf("usage: %s filename\n", argv[0]);
		exit(1);
	}
	if((fp=fopen(argv[1], "r")) == NULL){
		printf("can't open %s\n", argv[1]);
		exit(2);
	}
	while(fread(&acdata, sizeof(acdata), 1, fp) == 1){
		printf(FMT, (int)sizeof(acdata.ac_comm),
			(int)sizeof(acdata.ac_comm), acdata.ac_comm,
		#if defined(BSD)
			acdata.ac_etime, acdata.ac_io,
		#else
			compt2ulong(acdata.ac_etime), compt2ulong(acdata.ac_io),
		#endif
		#if defined(HAS_AC_STAT)
			(unsigned char)acdata.ac_stat,
		#endif
			acdata.ac_flag & ACORE ? 'D': '-',
			acdata.ac_flag & AXSIG ? 'X': '-',
			acdata.ac_flag & AFORK ? 'F': '-',
			acdata.ac_flag & ASU   ? 'S': '-');
	}
	if(ferror(fp))
		printf("read error\n");
	exit(0);
}

    BSD 派生的平台不支持 ac_stat 成员,所以我们在支持该成员的平台上定义了 HAS_AC_STAT 产量。同理,我们还定义了类似的常量以判断该平台是否支持 ACORE 和 AXSIG 会计标志,不能直接使用这两个标志符号,因为它们在 Linux 中被定义为 enum 类型值,而在 #ifdef 中不能使用此种类型值。
    为进行测试,需要执行下列操作步骤。
    (1)成为超级用户,用 accton 命令启用会计处理。注意,当此命令结束时,会计处理已经启用,因此会计文件中的第一个记录应来自这一命令。
    (2)终止超级用户 shell,运行上面的 acctDemo 程序,这会追加 6 个记录到会计文件中(超级用户 shell 一个、父进程一个、4 个子进程各一个)。注意,第二个子进程中的 execl 并不创建一个新进程,所以只有一个会计记录。
    (3)成为超级用户,停止会计处理。因为在 accton 命令终止时已经停止会计处理,所以不会在会计文件中增加一个记录。
    (4)运行 printAcct 程序,从会计文件中选出字段并打印。
    整个流程在 Solaris 上的运行结果如下:
$ ls -l /var/adm/pacct 
-rw-r--r--. 1 root root 0 9月  13 23:57 /var/adm/pacct
$ 
$ su
密码:
# accton /var/adm/pacct       # 打开进程会计
# ./acctDemo.out
# accton                      # 关闭进程会计
#
# ./printAcct.out /var/adm/pacct
accton        e =      1, chars =       336, stat =   0: - - - S
sh            e =   1550, chars =     20168, stat =   0: - - - S
dd            e =      2, chars =      1585, stat =   0: - - - -   # 第二个子进程
acctDemo.out  e=     202, chars=          0, stat =   0: - - - -   # 父进程
acctDemo.out  e=     420, chars=          0, stat = 134: - - F -   # 第一个子进程
acctDemo.out  e=     600, chars=          0, stat =   0: - - F -   # 第四个子进程
acctDemo.out  e=     801, chars=          0, stat =   0: - - F -   # 第三个子进程

    注意,ac_stat 成员并不是真正的终止状态,而只是其中的一部分。如果进程异常终止,则此字节包含的信息只是 core 标志位(一般是最高位)以及信号编号数(一般是低 7 位);如果进程正常终止,则从会计文件不能得到进程的退出(exit)状态。
  • 大小: 9.1 KB
  • 大小: 8.7 KB
分享到:
评论

相关推荐

    acct进程会计

    "acct进程会计"是Linux和Unix系统中用于记录和分析系统中进程活动的重要工具。它通过对每个进程产生的系统调用和资源使用情况进行跟踪,为系统管理员提供了宝贵的审计数据,帮助理解系统的运行状况、查找性能瓶颈...

    arm-gic.rar_GIC-400_gic

    进程会计是一种系统监控技术,它记录了系统中每个进程的详细运行信息,如执行时间、资源使用情况等,有助于系统管理员分析系统的性能和资源消耗。 标签 "gic-400" 和 "gic" 强调了主题是与 GIC-400 相关的内容,而 ...

    AIX命令手册a-c

    - **功能**:用于编辑进程会计数据,如修改进程的会计属性。 - **选项**: - `-p`:修改进程的会计属性。 - `-l`:列出当前进程的会计属性。 - `-d`:删除进程的会计属性。 #### 11. aclget - 获取访问控制列表 ...

    UNIX环境高级编程pdf_08

    此外,书中还提到了进程会计机制,这是一个监视和记录系统资源使用情况的特性,比如CPU时间、内存使用等,为系统管理员提供了监控系统性能的工具。 关于`fork()`,现代实现往往采用写时复制技术来优化内存管理。当...

    中国会计电算化发展进程与趋势研究-论文.zip

    《中国会计电算化发展进程与趋势研究》这篇论文深入探讨了我国会计电算化的发展历程、当前状态以及未来可能的趋势。会计电算化是指利用计算机技术,将会计业务处理自动化,提高会计工作效率,减少人为错误的过程。这...

    The Linux Process Manager

    Linux内核提供了进程会计机制,可以帮助管理员监控系统的资源使用情况,识别资源消耗高的进程,并采取相应的措施。 #### 二十四、虚拟8086模式 虚拟8086模式是Linux内核提供的一种运行旧版16位应用程序的方法。在...

    UNIX环境高级编程08

    此外,本章还提到了进程会计机制,这是一个用于记录和分析进程运行情况的系统特性,它提供了对进程控制功能的另一个观察视角。通过学习这一章,开发者可以更好地理解和控制UNIX系统中的进程行为,进行更高级的系统...

    会计岗位有哪些[试析会计信息化进程中会计人员能力的培养].pdf

    这一进程不仅提高了会计工作的效率,也为企业的决策提供了更为准确和及时的信息支持。 会计信息化的内涵非常广泛,它涵盖了会计理论、实务、教育以及政府会计管理等多个方面。在功能上,它不仅仅是会计核算,还涉及...

    会计业务在信息化进程中的操作流程【会计实务操作教程】.pptx

    在这一变革中,信息化进程不仅是技术手段的更新,更是整个会计行业工作方式、思维模式以及管理理念的深刻转变。本文将深入探讨会计业务在信息化进程中的操作流程及其所面临的挑战,并提出相应的解决策略。 传统会计...

    会计总账元数据标准化:加速会计信息化进程【会计实务操作教程】.pptx

    会计总账元数据标准化:加速会计信息化进程【会计实务操作教程】.pptx

    acct-6.6.4 源码包

    监视Linux用户活动 对每个想密切监视其服务器/系统上用户...accton命令用于开启/关闭进程会计机制(process accounting)。 sa命令用于概述之前执行的命令的信息。 last和lastb这两个命令显示了最近登录用户的列表。

    Linux 2.6.19.x 内核编译配置选项简介【作者:金步国】

    这个选项提供了另一种获取任务或进程统计信息的方式,与BSD进程会计不同的是,这些统计信息在整个任务或进程的生命周期中都可用。 **11. 启用进程等待资源统计 (Enable per-task delay accounting)** 选择此项会在...

    内核配置参考

    Netlink是一种用户空间与内核空间之间高效通信的机制,通过它可以在整个任务生命周期内持续收集和传输进程统计信息,相较于传统的进程会计,提供了更实时和细粒度的数据。 ### 审计支持 #### 系统调用审计 支持对...

    内核编译配置选项简介

    - **通过Netlink接口导出任务/进程统计信息**:这是一种不同于BSD进程会计的方式,它可以持续地收集并提供进程信息。 - **启用按任务延迟计费**:记录进程等待系统资源(如CPU时间、I/O操作)的时间。 - **UTS命名...

    Linux系统编程学习笔记

    - **system/进程会计和时间**: `system` 函数可以执行外部命令,进程会计则是跟踪进程资源使用情况的机制。 - **守护进程**: 守护进程是一种特殊类型的进程,它在后台运行并且与终端脱离关联。 - **系统日志**: ...

    Linux内核编译配置选项简介

    8. BSD进程会计版本3文件格式(BSD Process Accounting version 3 file format) 使用新的第三版文件格式可以包含每个进程的PID以及其父进程的PID,但它与旧版本的文件格式不兼容。 9. 通过netlink接口导出任务/...

    人工智能会计进程中会计人员的抉择.pdf

    人工智能在会计行业中的应用及其对会计人员的影响是一个复杂且持续发展的议题。人工智能(AI)作为科技与人类智慧结合的产物,正在改变着社会经济生活的各个层面,会计作为记录和管理经济活动的重要手段,自然也受到...

Global site tag (gtag.js) - Google Analytics