linux中的时间编程和实现原理

上传人:第*** 文档编号:32688114 上传时间:2018-02-12 格式:DOC 页数:17 大小:178.50KB
返回 下载 相关 举报
linux中的时间编程和实现原理_第1页
第1页 / 共17页
linux中的时间编程和实现原理_第2页
第2页 / 共17页
linux中的时间编程和实现原理_第3页
第3页 / 共17页
linux中的时间编程和实现原理_第4页
第4页 / 共17页
linux中的时间编程和实现原理_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《linux中的时间编程和实现原理》由会员分享,可在线阅读,更多相关《linux中的时间编程和实现原理(17页珍藏版)》请在金锄头文库上搜索。

1、Linux 中的时间编程和实现原理本文试图完整地描述 Linux 系统中 C 语言编程中的时间问题。主要内容包括应用程序中的时间编程方法;时钟硬件简介;Glibc 时间函数的实现以及 Linux 内核对时间的支持和实现原理。这一部分,探讨应用开发中的时间编程问题。引子我们都生活在时间中,但却无法去思考它。什么是时间呢?似乎这是一个永远也不能被回答的问题。然而作为一个程序员,在工作中,总有那么几次我必须思考什么是时间。比如,需要知道一段代码运行了多久;要在 log 文件中记录事件发生时的时间戳;再比如需要一个定时器以便能够定期做某些计算机操作。我发现,在计算机世界中,时间在不同场合也往往有不同的

2、含义,让试图思考它的人感到迷茫。但值得庆幸的是,Linux 中的时间终究是可以理解的。因此我打算讨论一下有关时间的话题,尝试着深入理解 Linux 系统中 C 语言编程中的时间问题。主要内容如下: 第 1 部分是应用程序中的时间问题。有三个方面:程序计时需要;获取当前时间;定时器。 第 2 部分包括时间硬件简介和 GlibC 实现时间函数的原理。 第 3 和第 4 部分是 Linux 内核对时间的支持和实现原理。现在开始第 1 部分,探讨应用开发中的时间编程问题。在这一部分中,所有的例子代码都在 GlibC 2.14,内核 2.6.33 的 Linux 系统下编译并验证执行过。读者如果使用低版

3、本的 GlibC 和 Linux 内核有可能无法正确执行。获取当前时间时间的获取在程序当中, 我们经常要输出系统当前的时间,比如日志文件中的每一个事件都要记录其产生时间。在 C 语言中获取当前时间的方法有以下几种,它们所获得的时间精度从秒级到纳秒,各有所不同。表 1. C 时间函数function 定义 含义 返回值 精度 time() time 函数获得从 1970 年 1 月 1 日 0 点到当前的秒数,存储在 time_t 结构之中。 time_t 秒 gettimeofday() gettimeofday 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用 time

4、val 数据结构表示。 struct timevaltime_t tv_sec;long int tv_usec;微秒 clock_gettime() clock_gettime 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用 timespec 数据结构表示。支持不广泛。属于实时扩展。struct timespectime_t tv_sec;long int tv_nsec; 纳秒 ftime() 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用timeb 数据结构表示。已经过时, 被 time() 替代。尽量不使用。 struct timeb t

5、ime_t time;unsigned short millitm;short timezone;short dstflag; 毫秒 GUN/Linux 提供了三个标准的 API 用来获取当前时间,time()/gettimeofday()/clock_gettime(),它们的区别仅在于获取的时间精度不同,您可以根据需要选取合适的调用。ftime() 是老的一些系统中的时间调用,很多 Linux 版本虽然支持它,但仅仅是为了向前兼容性,新开发的软件不建议使用 ftime() 来获得当前时间。时间显示和转换目前我们得到的时间是一个数字,无论精度如何,它代表的仅是一个差值。比如精度为秒的 tim

6、e() 函数,返回一个 time_t 类型的整数。假设当前时间为 2011 年 12 月 7 日下午 20 点 29 分 51 秒,那么 time_t 的值为:1323318591。即距离 1970 年 1 月 1 日零点,我们已经过去了 1323318591 秒。(这里的 1970 年 1 月 1 日零点是格林威治时间,而不是北京时间。)我们下面讨论的时间如果不特别说明都是格林威治时间,也叫 GMT 时间,或者 UTC 时间。字符串“1323318591 秒”对于多数人都没有太大的意义,我们更愿意看到“2011 年 12 月 7 日”这样的显示。因此当我们得到秒,毫秒,甚至纳秒表示的当前时间

7、之后,往往需要将这些数字转换为人们所熟悉的时间表示方法。由于国家,习惯和时区的不同,时间的表示方法并没有一个统一的格式。为了满足各种时间显示的需求,标准 C 库提供了许多时间格式转换的函数。这些函数的数量众多,容易让人迷惑,记住它们的用法十分不易。在这里我借用 Michael Kerrisk 在Linux Programming Interface一书中的插图,来对这些标准 C 函数进行一个总体的概览。图 1. 各种时间显示格式转换函数关系图从上图可以看到,time()/gettimeofday() 从内核得到当前时间之后,该当前时间值可以被两大类函数转换为更加容易阅读的显示格式: 固定格式转

8、换 用户指定格式转换函数。固定格式转换用 ctime() 函数转换出来的时间格式是系统固定的,调用者无法改动,因此被称为固定格式转换。如果您对日期格式没有特殊的要求,那么用它基本上就可以了,简单,不用记忆很多的参数。用户指定格式转换典型的 ctime() 格式如下:Wed Dec 7 20:45:43 PST 2011有些人觉得这个格式太长,类似 Wed,星期三这样的信息很多情况下都没有啥用途。人们可能更喜欢其他格式:比如 2011-12-07 20:45。在这种情况下,就需要进行时间显示格式转换。做法为:先把从内核得到的时间值转换为 struct tm 类型的值,然后调用 strftime(

9、) 等函数来输出自定义的时间格式字符串。下面我列举一些实例,以便读者更清晰地理解众多的时间转换函数的用法。各标准 C 时间转换函数的解释和举例char *ctime(const time_t *clock); 使用函数 ctime 将秒数转化为字符串. 这个函数的返回类型是固定的:一个可能值为”Thu Dec 7 14:58:59 2000”。这个字符串的长度和显示格式是固定的。清单 1,time 的使用#include int main ()time_t time_raw_format;time ( /获取当前时间printf ( time is %dn, time_raw_format);

10、/用 ctime 将时间转换为字符串输出printf ( The current local time: %s, ctime(return 0;自定义格式转换为了更灵活的显示,需要把类型 time_t 转换为 tm 数据结构。tm 数据结构将时间分别保存到代表年,月,日,时,分,秒等不同的变量中。不再是一个令人费解的 64 位整数了。这种数据结构是各种自定义格式转换函数所需要的输入形式。清单 2,数据结构 tmstruct tm int tm_sec; /* Seconds (0-60) */int tm_min; /* Minutes (0-59) */int tm_hour; /* Hou

11、rs (0-23) */int tm_mday; /* Day of the month (1-31) */int tm_mon; /* Month (0-11) */int tm_year; /* Year since 1900 */int tm_wday; /* Day of the week (Sunday = 0)*/int tm_yday; /* Day in the year (0-365; 1 Jan = 0)*/int tm_isdst; /* Daylight saving time flag 0: DST is in effect;= 0: DST is not effec

12、t;struct tm *gmtime(const time_t *timep);struct tm *localtime(const time_t *timep);使用 tm 来表示时间,您就可以调用 asctime() 和 strftime() 将时间转换为字符串了。asctime() 的输出格式固定,和 ctime() 相同。strftime() 则类似我们最熟悉的 printf() 函数,您可以通过输入参数自定义时间的输出格式。size_t strftime(char *outstr, size_t maxsize, const char *format,const struct tm

13、 *timeptr);清单 4,时间显示转换int main ()time_t time_raw_format;struct tm * time_struct;char buf 100;time ( time_struct = localtime ( strftime (buf,100,It is now: %I:%M%p.,time_struct);puts (buf);return 0;该例子程序的输出结果如下:It is now: 02:45PM.从以上的例子可以看到,利用从 time() 得到的时间值,可以调用各种转换函数将其转换成更方便人们阅读的形式。此外从前面的总结中我们也了解到,

14、还有两个 C 函数可以获得当前时间,gettimeofday() 以及 clock_gettime(),它们分别返回 struct timeval 或者 timespec 代表的高精度的时间值。在目前的 GLibC 中,还没有直接把 struct timeval/timespec 转换为 struct tm 的函数。一般的做法是将 timeval 中的 tv_sec 转换为 tm,使用上面所述的方法转换为字符串,最后在显示的时候追加上 tv_usec,比如下面的例子代码:清单 5,更多时间显示转换struct timeval tv;time_t nowtime; struct tm *nowt

15、m; char tmbuf64, buf64; gettimeofday( /获取当前时间到 tvnowtime = tv.tv_sec; /nowtime 存储了秒级的时间值nowtm = localtime( /转换为 tm 数据结构/用 strftime 函数将 tv 转换为字符串,但 strftime 函数只能达到秒级精度strftime(tmbuf, sizeof tmbuf, %Y-%m-%d %H:%M:%S, nowtm);/将毫秒值追加到 strftime 转换的字符串末尾 snprintf(buf, sizeof buf, %s.%06d, tmbuf, tv.tv_use

16、c);时间的测量有时候我们要计算某段程序执行的时间,比如需要对算法进行时间分析。基本的实现思路为在被测试代码的开始和结束的地方获取当时时间,相减后得到相对值,即所需要的统计时间。为了实现高精度的时间测量,必须使用高精度的时间获取方式,一般有两种方法: 系统调用 gettimeofday 汇编指令 RDTSC。gettimeofday可以使用 gettimeofday() 函数进行时间测量,其精度在 us 级别,可以用来做一般的时间分析。gettimeofday() 将时间保存在结构 tv 之中。gettimeofday() 的第二个参数代表时区,在 Linux 中已经废弃不用,只能用 NULL 传入。一个典型的例子程序如下:清单 6,gettimeofday 例子程序void function() unsigned int i,j; double y; for(i=0;iit_interval 为定时器的周期值,比如 1 秒,表示定时器每隔

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 职业教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号