http://www.cnblogs.com/suzhou/p/4383259.html
当一个进程终止时,内核会为该进程保存一些数据,包括命令的小部分二进制数据、CPU time、启动时间、用户Id和组Id。这样的过程称为process accounting,本篇译为进程快照。
函数acct可以打开或关闭进程快照功能。
负责记录快照的数据结构如下所示:
成员说明:
ac_flag不同的取值代表的事件含义如下表所示:
进程可以知道它的真实用户和组(real user ID and group ID),有效用户和组(effective user ID and group ID)。
然后有时候我们想知道运行程序的登录用户名。函数getpwuid可以实现。
函数声明:
#include <unistd.h>
char* getlogin(void);
// Returns: pointer to string giving login name if OK, NULL on error
函数细节:
nice值决定了进程的运行优先级。
取值范围:0 ~ (2 * NZERO -1)
nice值越低,优先级越高。
意思就是:进程越好,进程的优先级越高。
nice值的默认值为NZERO。
函数nice可以获取并修改nice值。
进程调用nice函数只能修改它自己的nice值。
函数声明:
#include <unistd.h>
int nice(int incr);
// Returns: new nice value - NZERO if OK, -1 on error
函数说明:
函数getpriority可以用来获取一个进程的nice值。
函数声明:
#include <sys/resource.h>
int getpriority(int which , id_t who);
// Returns: nice value between -NZERO和NZERO-1之间 if OK, -1 on error
参数说明:
which:有三个可取值:PRIO_PROCESS表明是一个进程,PRIO_PGRP表明是一个进程组,PRIO_USER表明目标是一个用户。
which参数的作用是控制who的含义,以及who参数如何选择进程。
如果who取值为0,则函数返回当前调用进程、进程组或用户的nice值。
如果which取值为PRIO_USER,who取值0,则返回当前进程的真实用户ID(real user Id)。
如果which取值为PRIO_GROUP,则返回所有进程中priority最高,即nice值最低的进程的nice值。
设置nice值使用函数setpriority。
函数声明:
#include <sys/resource.h>
int setpriority(int which, id_t who, int value);
参数的作用和getpriority相同。
value的值被加到nice默认值NZERO上,设置该值为新的nice值。
进程时间包括:墙上时间(wall clock tie),用户CPU时间(user CPU time),内核CPU时间(system CPU time).
函数times可以获取这三种时间。
函数声明:
#include <sys/times.h>
clock_t times(struct tms *buf);
函数细节:
函数会向结构体struct tms类型的变量中填充上面的三个时间,struct tms结构体的声明如下:
墙上时间为该函数的返回值。墙上时间为从过去某个时间点到现在的时间,所以不能直接作为时间来使用。
大多情况下,我们可以通过times的返回值来计算相对时间,例如,在进程开始和结束时分别调用times函数,然后相减来计算进程的运行时间。
两个子进程时间变量用来保存父进程调用wait函数等待子进程退出的时间。
程序功能:执行命令行传入的命令,计算每个命令执行的时间,并打印结构体tms中的成员值。
code
#include "apue.h"
#include <sys/times.h>
static void pr_times(clock_t, struct tms *, struct tms *);
staticvoid do_cmd(char *);
int
main(int argc, char *argv[])
{
int i;
setbuf(stdout, NULL);
for (i = 1; i < argc; i++)
do_cmd(argv[i]); /* once for each command-line arg */
exit(0);
}
staticvoid
do_cmd(char *cmd) /* execute and time the "cmd" */
{
struct tms tmsstart, tmsend;
clock_t start, end;
int status;
printf("\ncommand: %s\n", cmd);
if ((start = times(&tmsstart)) == -1) /* starting values */
err_sys("times error");
if ((status = system(cmd)) < 0) /* execute command */
err_sys("system() error");
if ((end = times(&tmsend)) == -1) /* ending values */
err_sys("times error");
pr_times(end-start, &tmsstart, &tmsend);
pr_exit(status);
}
staticvoid
pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend)
{
static long clktck = 0;
if (clktck == 0) /* fetch clock ticks per second first time */
if ((clktck = sysconf(_SC_CLK_TCK)) < 0)
err_sys("sysconf error");
printf(" real: %7.2f\n", real / (double) clktck);
printf(" user: %7.2f\n",
(tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck);
printf(" sys: %7.2f\n",
(tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck);
printf(" child user: %7.2f\n",
(tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck);
printf(" child sys: %7.2f\n",
(tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck);
}
进程控制章节介绍了以下内容:
下一章我们将会学习到进程关系(process relationship),关键字:sessions,job control。
参考资料:
《Advanced Programming in the UNIX Envinronment 3rd》