第七章 系统信息与系统资源(7.3 -7.5)

7.3 进程时间

        进程时间指的是进程从创建后(也就是程序运行后)到目前为止这段时间内使用 CPU 资源的时间总数,出于记录的目的,内核把 CPU 时间(进程时间)分为以下两个部分:
        ⚫ 用户 CPU 时间:进程在用户空间(用户态)下运行所花费的 CPU 时间。有时也成为虚拟时间(virtual time)。
        ⚫ 系统 CPU 时间:进程在内核空间(内核态)下运行所花费的 CPU 时间。这是内核执行系统调用或代表进程执行的其它任务(譬如,服务页错误)所花费的时间。
        一般来说,进程时间指的是用户 CPU 时间和系统 CPU 时间的总和,也就是总的 CPU 时间。

        进程时间不等于程序的整个生命周期所消耗的时间,如果进程一直处于休眠状态(进程被挂起、不会得到系统调度),那么它并不会使用 CPU 资源,所以休眠的这段时间并不计算在进程时间中。

7.3.1 times 函数

        times()函数用于获取当前进程时间。

#include <sys/times.h>
clock_t times(struct tms *buf);

/*函数参数/:
    buf:times()会将当前进程时间信息存在一个 struct tms 结构体数据中,
返回值:
    返回值类型为 clock_t(实质是 long 类型)。
    调用成功情况下,将返回从过去任意的一个时间点(譬如系统启动时间)所经过的时钟滴答数(其实就是系统节拍数),将(节拍数 / 节拍率)便可得到秒数,返回值可能会超过 clock_t 所能表示的范围(溢出);
    调用失败返回-1,并设置 errno。*/

         struct tms 结构体内容如下所示:

struct tms {
clock_t tms_utime; /* user time, 进程的用户 CPU 时间, tms_utime 个系统节拍数 */
clock_t tms_stime; /* system time, 进程的系统 CPU 时间, tms_stime 个系统节拍数 */
clock_t tms_cutime; /* user time of children, 已死掉子进程的 tms_utime + tms_cutime 时间总和 */
clock_t tms_cstime; /* system time of children, 已死掉子进程的 tms_stime + tms_cstime 时间总和 */
};

        总的进程时间 = 用户 CPU 时间 + 系统 CPU 时间

        以下我们演示了通过 times()来计算程序中某一段代码执行所耗费的进程时间和总的时间,测试程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    struct tms t_buf_start;
    struct tms t_buf_end;
    clock_t t_start;
    clock_t t_end;
    long tck;
    int i, j;
    /* 获取系统的节拍率 */
    tck = sysconf(_SC_CLK_TCK);
    /* 开始时间 */
    t_start = times(&t_buf_start);
    if (-1 == t_start) {
        perror("times error");
        exit(-1);
    }
/* *****需要进行测试的代码段***** */
    for (i = 0; i < 20000; i++)
    for (j = 0; j < 20000; j++)
    ;

        sleep(1);
    //休眠挂起
    /* *************end************** */
    /* 结束时间 */
    t_end = times(&t_buf_end);
    if (-1 == t_end) {
        perror("times error");
        exit(-1);
    }
    /* 打印时间 */
    printf("时间总和: %f 秒\n", (t_end - t_start) / (double)tck);
    printf("用户 CPU 时间: %f 秒\n", (t_buf_end.tms_utime - t_buf_start.tms_utime) / (double)tck);
    printf("系统 CPU 时间: %f 秒\n", (t_buf_end.tms_stime - t_buf_start.tms_stime) / (double)tck);
    exit(0);
}


7.3.2 clock 函数

        库函数 clock()提供了一个更为简单的方式用于进程时间,它的返回值描述了进程使用的总的 CPU 时间(也就是进程时间,包括用户 CPU 时间和系统 CPU 时间)。

#include <time.h>
clock_t clock(void);

/*函数参数:
    无参数。
返回值:
    返回值是到目前为止程序的进程时间,为 clock_t 类型,
    注意 clock()的返回值并不是系统节拍数,如果想要获得秒数,请除以 CLOCKS_PER_SEC(这是一个宏)。
    如果返回的进程时间不可用或其值无法表示,则该返回值是-1。*/    

        clock()函数虽然可以很方便的获取总的进程时间,但并不能获取到单独的用户 CPU 时间和系统 CPU 时间,在实际编程当中,根据自己的需要选择。

7.4 产生随机数

        在应用编程当中可能会用到随机数,譬如老板让你编写一个抽奖的小程序,编号 0~100,分为特等奖 1个、一等奖 2 个、二等级 3 以及三等级 4 个,也就是说需要从 0~100 个编号中每次随机抽取一个号码,这就需要用到随机数。

随机数与伪随机数 

        随机数是随机出现,没有任何规律的一组数列。在我们编程当中,是没有办法获得真正意义上的随机数列的,这是一种理想的情况,在我们的程序当中想要使用随机数列,只能通过算法得到一个伪随机数序列,那在编程当中说到的随机数,基本都是指伪随机数。

rand 函数

        rand()函数用于获取随机数,多次调用 rand()可得到一组随机数序列。

其函数原型如下:
#include <stdlib.h>
int rand(void);

/*返回值:
    返回一个介于 0 到 RAND_MAX(包含)之间的值,也就是数学上的[0, RAND_MAX]。*/

        程序当中调用 rand()可以得到[0, RAND_MAX]之间的伪随机数,多次调用 rand()便可以生成一组伪随机数序列。
        但是这里有个问题,就是每一次运行程序所得到的随机数序列都是相同的,那如何使得每一次启动应用程序所得到的随机数序列是不一样的呢?那就通过设置不同的随机数种子,可通过 srand()设置随机数种子。
        如果没有调用 srand()设置随机数种子的情况下,rand()会将 1 作为随机数种子,如果随机数种子相同,那么每一次启动应用程序所得到的随机数序列就是一样的,所以每次启动应用程序需要设置不同的随机数种子,这样就可以使得程序每次运行所得到随机数序列不同。

srand 函数

        使用 srand()函数为 rand()设置随机数种子。

#include <stdlib.h>
void srand(unsigned int seed);

/*函数参数:
    seed:指定一个随机数中,int 类型的数据,一般尝尝将当前时间作为随机数种子赋值给参数 seed。
    譬如 time(NULL),因为每次启动应用程序时间上是一样的,所以就能够使得程序中设置的随机数种子在每次
启动程序时是不一样的。*/

                常用的用法 srand(time(NULL));

        每一次得到的[0~100]之间的随机数数组都是不同的(数组不同,不是产生的随机数不同),
        因为程序中将 rand()的随机数种子设置为 srand(time(NULL)),直接等于 time_t 时间值,意味着每次启动种子都不一样,所以能够产生不同的随机数数组。

7.5 休眠

       系统有时需要将进程暂停或休眠一段时间,进入休眠状态之后,程序将暂停运行,直到休眠结束。

7.5.1 秒级休眠: sleep

/* 让程序休眠 3 秒钟 */
sleep(3);

7.5.2 微秒级休眠: usleep

/* 让程序休眠 3 秒钟(3*1000*1000 微秒) */
usleep(3 * 1000 * 1000);

7.5.3 高精度休眠: nanosleep

        nanosleep()与 sleep()以及 usleep()类似,都用于程序休眠,但 nanosleep()具有更高精度来设置休眠时间长度,支持纳秒级时长设置。与 sleep()、usleep()不同的是,nanosleep()是一个 Linux 系统调用。

#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);

/*函数参数与返回值含义如下:
    req:一个 struct timespec 结构体指针,指向一个 struct timespec 变量,
    用于设置休眠时间长度,可精确到纳秒级别。
    rem:也是一个 struct timespec 结构体指针,指向一个 struct timespec 变量,
    也可设置 NULL。
返回值:
    在成功休眠达到请求的时间间隔后,nanosleep()返回 0;
    如果中途被信号中断或遇到错误,则返回-1,
    并将剩余时间记录在参数 rem 指向的 struct timespec 结构体变量中
    (参数 rem 不为 NULL 的情况下,如果为 NULL 表示不接收剩余时间),
    还会设置 errno 标识错误类型。*/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值