- 浏览: 142477 次
文章分类
最新评论
大多数 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>中,虽然每种系统的实现各不相同,但会计记录样式基本如下:
其中 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,每个子进程做不同的事情,然后终止。
然后可使用下面这个程序 printAcct 来打印运行上面程序后产生的会计数据。
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 上的运行结果如下:
注意,ac_stat 成员并不是真正的终止状态,而只是其中的一部分。如果进程异常终止,则此字节包含的信息只是 core 标志位(一般是最高位)以及信号编号数(一般是低 7 位);如果进程正常终止,则从会计文件不能得到进程的退出(exit)状态。
会计记录结构定义在头文件<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)状态。
发表评论
-
打开伪终端设备
2018-07-09 20:50 1252在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1550伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 800多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 950终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 569尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 944虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 710tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 815终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 439终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 579在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 947在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 617在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 497消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 485有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 421FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 389管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 891readv 和 writev 函数可用于在一次函数调用 ... -
POSIX 异步 I/O
2018-01-16 21:33 455POSIX 异步 I/O 接口为对不同类型的文件进行异 ... -
fcntl 记录锁
2018-01-06 23:48 615记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 439UNIX 系统中,守护进程遵循下列通用惯例。 ...
相关推荐
"acct进程会计"是Linux和Unix系统中用于记录和分析系统中进程活动的重要工具。它通过对每个进程产生的系统调用和资源使用情况进行跟踪,为系统管理员提供了宝贵的审计数据,帮助理解系统的运行状况、查找性能瓶颈...
进程会计是一种系统监控技术,它记录了系统中每个进程的详细运行信息,如执行时间、资源使用情况等,有助于系统管理员分析系统的性能和资源消耗。 标签 "gic-400" 和 "gic" 强调了主题是与 GIC-400 相关的内容,而 ...
- **功能**:用于编辑进程会计数据,如修改进程的会计属性。 - **选项**: - `-p`:修改进程的会计属性。 - `-l`:列出当前进程的会计属性。 - `-d`:删除进程的会计属性。 #### 11. aclget - 获取访问控制列表 ...
此外,书中还提到了进程会计机制,这是一个监视和记录系统资源使用情况的特性,比如CPU时间、内存使用等,为系统管理员提供了监控系统性能的工具。 关于`fork()`,现代实现往往采用写时复制技术来优化内存管理。当...
《中国会计电算化发展进程与趋势研究》这篇论文深入探讨了我国会计电算化的发展历程、当前状态以及未来可能的趋势。会计电算化是指利用计算机技术,将会计业务处理自动化,提高会计工作效率,减少人为错误的过程。这...
Linux内核提供了进程会计机制,可以帮助管理员监控系统的资源使用情况,识别资源消耗高的进程,并采取相应的措施。 #### 二十四、虚拟8086模式 虚拟8086模式是Linux内核提供的一种运行旧版16位应用程序的方法。在...
此外,本章还提到了进程会计机制,这是一个用于记录和分析进程运行情况的系统特性,它提供了对进程控制功能的另一个观察视角。通过学习这一章,开发者可以更好地理解和控制UNIX系统中的进程行为,进行更高级的系统...
这一进程不仅提高了会计工作的效率,也为企业的决策提供了更为准确和及时的信息支持。 会计信息化的内涵非常广泛,它涵盖了会计理论、实务、教育以及政府会计管理等多个方面。在功能上,它不仅仅是会计核算,还涉及...
在这一变革中,信息化进程不仅是技术手段的更新,更是整个会计行业工作方式、思维模式以及管理理念的深刻转变。本文将深入探讨会计业务在信息化进程中的操作流程及其所面临的挑战,并提出相应的解决策略。 传统会计...
会计总账元数据标准化:加速会计信息化进程【会计实务操作教程】.pptx
监视Linux用户活动 对每个想密切监视其服务器/系统上用户...accton命令用于开启/关闭进程会计机制(process accounting)。 sa命令用于概述之前执行的命令的信息。 last和lastb这两个命令显示了最近登录用户的列表。
这个选项提供了另一种获取任务或进程统计信息的方式,与BSD进程会计不同的是,这些统计信息在整个任务或进程的生命周期中都可用。 **11. 启用进程等待资源统计 (Enable per-task delay accounting)** 选择此项会在...
Netlink是一种用户空间与内核空间之间高效通信的机制,通过它可以在整个任务生命周期内持续收集和传输进程统计信息,相较于传统的进程会计,提供了更实时和细粒度的数据。 ### 审计支持 #### 系统调用审计 支持对...
- **通过Netlink接口导出任务/进程统计信息**:这是一种不同于BSD进程会计的方式,它可以持续地收集并提供进程信息。 - **启用按任务延迟计费**:记录进程等待系统资源(如CPU时间、I/O操作)的时间。 - **UTS命名...
- **system/进程会计和时间**: `system` 函数可以执行外部命令,进程会计则是跟踪进程资源使用情况的机制。 - **守护进程**: 守护进程是一种特殊类型的进程,它在后台运行并且与终端脱离关联。 - **系统日志**: ...
8. BSD进程会计版本3文件格式(BSD Process Accounting version 3 file format) 使用新的第三版文件格式可以包含每个进程的PID以及其父进程的PID,但它与旧版本的文件格式不兼容。 9. 通过netlink接口导出任务/...
人工智能在会计行业中的应用及其对会计人员的影响是一个复杂且持续发展的议题。人工智能(AI)作为科技与人类智慧结合的产物,正在改变着社会经济生活的各个层面,会计作为记录和管理经济活动的重要手段,自然也受到...