前言

clock_gettime 是一个 POSIX 函数,用于获取系统的时间。它提供了一种精确且高分辨率的方式来获取时间信息,适合在各种场景中使用,如测量时间间隔、实现超时功能或者进行性能分析。

函数原型如下:

#include <time.h>

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

参数说明

  • clk_id:指定时钟的类型,决定了函数返回的时间值的参考源。常见的时钟类型包括:
  • CLOCK_REALTIME:系统实时时钟,表示从 Epoch(通常为 1970 年 1 月 1 日 0 点 0 分 0 秒 UTC)到当前的时间。
  • CLOCK_MONOTONIC:单调时钟,表示从某个未指定的起点到现在的时间,不受系统时间设置的影响。适用于测量时间间隔。
  • CLOCK_PROCESS_CPUTIME_ID:进程执行时间,表示当前进程消耗的 CPU 时间。
  • CLOCK_THREAD_CPUTIME_ID:线程执行时间,表示当前线程消耗的 CPU 时间。
  • tp:指向 struct timespec 结构的指针,用于存储获取到的时间值。

struct timespec 结构

struct timespec 定义在 <time.h> 头文件中,包含以下成员:

struct timespec {
    time_t tv_sec;  // 秒
    long tv_nsec;   // 纳秒
};

返回值

  • 成功时返回 0。
  • 失败时返回 -1,并设置 errno 以指示错误原因。

一、标准时间转换

标准时间即人类可读时间,此处介绍一种将RT时钟和单调时钟转化的方法

代码示例

#include <stdio.h>
#include <time.h>

void print_human_readable_time(struct timespec ts, const char *description) {
    char buffer[256];
    struct tm *tm_info;

    // tv_sec 是从 Unix 纪元(1970-01-01 00:00:00)开始的秒数
    tm_info = localtime(&ts.tv_sec);

    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
    printf("%s: %s.%09ld\n", description, buffer, ts.tv_nsec);
}

int main() {
    struct timespec ts_realtime, ts_monotonic;

    if (clock_gettime(CLOCK_REALTIME, &ts_realtime) == -1) {
        perror("clock_gettime(CLOCK_REALTIME) failed");
        return 1;
    } 

    printf("ts_realtime.tv_sec: %ld\n", ts_realtime.tv_sec);
    printf("ts_realtime.tv_nsec: %ld\n", ts_realtime.tv_nsec);

    if (clock_gettime(CLOCK_MONOTONIC, &ts_monotonic) == -1) {
        perror("clock_gettime(CLOCK_MONOTONIC) failed");
        return 1;
    } 

    printf("ts_monotonic.tv_sec: %ld\n", ts_monotonic.tv_sec);
    printf("ts_monotonic.tv_nsec: %ld\n", ts_monotonic.tv_nsec);
    

    print_human_readable_time(ts_realtime, "CLOCK_REALTIME");
    print_human_readable_time(ts_monotonic, "CLOCK_MONOTONIC");

    return 0;
}

输出结果示例

ts_realtime.tv_sec: 1724120767
ts_realtime.tv_nsec: 250334428
ts_monotonic.tv_sec: 56574
ts_monotonic.tv_nsec: 956233085
CLOCK_REALTIME: 2024-08-20 11:26:07.250334428
CLOCK_MONOTONIC: 1970-01-02 00:42:54.956233085