linux系统中的时间及操作函数

来源:互联网 发布:弥塞拉 知乎 编辑:程序博客网 时间:2024/04/30 13:21


(一)Linux系统中的时间


rtc

由rtc芯片提供的时间,可以转换为格林尼治时间,linux中把这一类时间称为wall time,墙上时间。rtc时间由rtc芯片来维护更新,它通常由一个专门的计时硬件来实现,软件可以读取该硬件来获得年月日、时分秒等时间信息。rtc时间是可持续计时的,通常硬件上会加上一个后备电池供电,这样即使系统关闭,rtc时间依然是正常更新的,这样就可以保证下次系统起来的时候可以从rtc芯片中,重新读取到正确的墙上时间。

xtime

linux系统时间是用从Epoch(1970年1月1日00:00:00 UTC)开始所经过的时间来表示,比如unix时间戳就是从Epoch开始所经过的秒数。这种时间表述方法可以很方便的转化成我们常用的格林尼治时间,所以它也是一种墙上时间。

monotonic time

单调增长的系统运行时间(ntp影响其单调性), 记录的是从系统启动以来到当前的时间间隔,它不会像xtime一样可以被用户修改而发生跳变。不过该时间不计算休眠时间。

raw monotonic time

raw monotonic time: 该时间与monotonic时间类似,也是单调递增的时间,唯一的不同是,raw monotonic time不会受到NTP时间调整的影响,它代表着系统独立时钟硬件对时间的统计。

boot time 

它代表着系统上电后的总时间,包括了休眠时间。


ntp服务会全部影响到上面提到的几种时间类型。ntp就是为了校正时间的服务,为了每次启动都能正确修改,所以rtc要更新,为了使当前时间也修改生效,所以xtime也要更新。


(二)时间操作函数


RTC时间操作:

1.rtc时间是由rtc硬件控制的,所以在linux中想要修改和获取rtc时间就只能通过驱动的接口来获取和修改。


int rtc_test(void){struct rtc_time rtc;int fd = -1;int ret = -1;fd = open("/dev/rtc0", O_RDWR);if (fd < 0){return -1;}ret = ioctl(fd, RTC_RD_TIME, &rtc);if (ret < 0){return -1;}printf("\nCurrentRTC data/time is %d-%d-%d, %02d:%02d:%02d.\n", rtc.tm_mday, rtc.tm_mon + 1,rtc.tm_year + 1900, rtc.tm_hour, rtc.tm_min, rtc.tm_sec);ret = ioctl(fd, RTC_SET_TIME, &rtc);if (ret < 0){return -1;}return 0;}

2.除了上面这种方式操作rtc时间以外,linux中也有一个命令可以简化rtc时间操作,hwclock,比如,可以通过system("hwclock -w");系统调用来把xtime设置到rtc硬件。

墙上时间(realtime、xtime):

linux系统中主要使用的就是xtime,它是系统运行的基础,很多程序都是依赖于xtime来运行的,接下来将介绍将如何操作xtime。

1.获取、设置微秒级别的时间:

    #include <sys/time.h>
    #include <unistd.h>

      struct timeval
       {
              inttv_sec;
              inttv_usec;
       }; 

int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv, const struct timezone *gz);
功能描述:

gettimeofday()获取当前时间,有tv指向的结构体返回。

settimeofday()把当前时间设成由tv指向的结构体数据。当前地区信息则设成tz指向的结构体数据。


2.获取秒级别的时间

typedef  long  time_t;

time_ttime(time_t *t);

如果tnon-null,它将会把时间值填入t


3.内核2.6版本后新增的clock api接口

获取纳秒级别的时间


struct  timespec{ 

  time_t tv_sec; /*s*/  

  long tv_nsec; /*纳秒ns*/ 
};


int clock_getres(clockid_t clk_id , struct timespec *res);

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

int clock_settime(clockid_t clk_id 、 const struct timespec *tp);

编译连接时采用-lrt才能编译通过。

clk_id可选参数:

CLOCK_REALTIME
系统全局的实时时钟.设置此时钟需要合适的权限.
CLOCK_MONOTONIC
只能被读取,无法被设置,表示 monotonic 时间起点.
CLOCK_PROCESS_CPUTIME_ID
从 cpu 每进程的高分辨率计时器.
CLOCK_THREAD_CPUTIME_ID

线程的特定 cpu 时间时钟.


系统启动时,会首先从rtc中读取rtc时间,并设置给xtime,而当ntp对系统时间进行更新时,首先设置xtime,然后调用hwclock设置到rtc硬件中。xtime根据需要的精度,可以通过上面几个接口来选择使用。






0 0