日度归档:2012 年 3 月 25 日

计算机系统中的时间

本文不完全的总结了 UNIX 环境编程中关于时间的操作。

计算机中有两种不同的时间参考系:一种为人们所熟悉的挂在墙上的时钟,即日历时间;另一种则为处理器时间,由于现代计算机系统一般为多任务系统,所以进程并不一直占用处理器。

计算机系统工作在数个不同的时间维度中,典型的 CPU 一个周期时间大约为 10^-9s, CPU 固定间隔时间的中断一般为 0.01s, 而人能够分辨的最小时间间隔在 0.1 s 左右。计算机能够提供的最小时间精度取决于其具体实现,一般计算机最少能提供其 CPU 时间片长度的时钟分辨率,一般为 10ms, 一些系统可以利用 CPU 周期数获取最高分辨率为 1ns 的时钟精度。

获取当前日期和时间

简单的,在 shell 中输入 date 命令即可打印出当前的日期和时间。

UNIX 系统提供的基本时间服务为国际标准时间公元1970年1月1日零点以来所经过的秒数,这个秒数是以数据类型 time_t 表示的,称为日历时间,可以使用 C 库函数 time 获得。另外 C 标准库 time.h 头文件中提供了一系列转换时间的函数,把 time 函数获得的秒数转换为可读的、本地的日期和时间。

#include <time.h>
time_t time(time_t *calptr); 

值得注意的是,time_t 被定义为 long int 类型,在32位系统中,最大只能表示到 2038 年左右。所幸随着64位系统的普及,这一问题将不复存在。

使用 gettimeofday 函数,能够获得比 time 函数具有更高分辨率的日历时间,最高能够达到微妙(10^-6s)级,但这取决与系统的具体实现。在有些平台上,操作系统能够使用 CPU 周期数来获取当前时间,能够达到微妙级的精度,但有些系统实现则使用系统时钟,一般只有 10ms (毫秒,10^-3s)的精度。

#include <sys/time.h>

struct timeval {
    long tv_sec; /* Seconds */
    long tv_usec; /* Microseconds */
}

int gettimeofday(struct timeval *tv, NULL);

在 linux 系统中,gettimeofday 的第二个参数应该简单的设置为 NULL, 因为它指向一个未被实现的校正时区的特性。

使用 clock_gettime 函数指定 clk_id 为 CLOCK_REALTIME 时可以获取系统纳秒级的日历时间。

#include <time.h>

struct timespec {
    time_t tv_sec; /* seconds */
    long tv_nsec; /* nanoseconds */
};

int clock_gettime(clockid_t clk_id, struct timespec *tp);

编译程序时需要链接 -lrt 库,否则会报错。

测量程序执行的时间

继续阅读