[8 进程控制]使用times计算进程处理时间

1 times介绍

我们可以度量的3个时间:墙上时钟时间,用户CPU时间和系统CPU时间。任一进程可调用times函数获得它自己以及已终止子进程的上述值。

#include <sys/times.h>
// 若成功,返回流逝的墙上时钟时间(以时钟滴答数为单位)
// 若失败,返回-1
clock_t times(struct tms *buf);

tms结构体定义:

struct tms {
    clock_t tms_utime;    //user CPU time
    clock_t tms_stime;    //system CPU time
    clock_t tms_cutime;   //user CPU time,terminated children
    clock_t tms_cstime;   //user CPU time,terminated children
};

times函数返回墙上时钟作为其函数返回值。此值是相对于过去某一时刻度量的,所以不能用其绝对值而必须使用其相对值。
例如,调用times保存其返回值,在以后某个时间再次调用times,从新返回的值中减去以前返回的值,此差值就是墙上时钟时间。
墙上时钟时间可以由_SC_CLK_TCK来转换为秒数。(由sysconf函数返回)

2 使用times计算进程处理时间

以下程序通过system函数将每个命令行参数执行,并对每个命令计时打印。
time.c:

#include <sys/times.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

static void pr_times(clock_t, struct tms *, struct tms *);
static void 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);
}

void pr_exit(int status)
{
    if (WIFEXITED(status))
        printf("normal termination, exit status = %d\n",
                WEXITSTATUS(status));
    else if (WIFSIGNALED(status))
        printf("abnormal termination, signal number = %d%s\n",
                WTERMSIG(status),
#ifdef    WCOREDUMP
                WCOREDUMP(status) ? " (core file generated)" : "");
#else
                "");
#endif
    else if (WIFSTOPPED(status))
        printf("child stopped, signal number = %d\n",
                WSTOPSIG(status));
}

static void 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 */
        printf("times error");

    if ((status = system(cmd)) < 0)            /* execute command */
        printf("system() error");

    if ((end = times(&tmsend)) == -1)        /* ending values */
        printf("times error");

    pr_times(end-start, &tmsstart, &tmsend);
    pr_exit(status);
}

static void 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)            //转化为秒
            printf("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);
}

测试如下:

./time "sleep 3"
command: sleep 3
  real:     3.01
  user:     0.00
  sys:      0.00
  child user:     0.00
  child sys:      0.00
normal termination, exit status = 0

./time "date"
command: date
2022年 05月 21日 星期六 11:36:59 CST
  real:     0.00
  user:     0.00
  sys:      0.00
  child user:     0.00
  child sys:      0.00
normal termination, exit status = 0

./time "man bash > /dev/null"
command: man bash > /dev/null
  real:     0.41
  user:     0.00
  sys:      0.00
  child user:     0.26
  child sys:      0.05
normal termination, exit status = 0

第1个命令表明墙上时钟时间转化为秒数后为3秒;第3个命令表明CPU时间大部分是消耗在子进程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值