Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2003680
  • 博文数量: 369
  • 博客积分: 10093
  • 博客等级: 上将
  • 技术积分: 4271
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-21 00:59
文章分类

全部博文(369)

文章存档

2013年(1)

2011年(2)

2010年(10)

2009年(16)

2008年(33)

2007年(146)

2006年(160)

2005年(1)

分类: LINUX

2008-03-17 23:51:23

今天,再次碰到一个由于系统时间调整导致的bug。不得不再次查找完美的问题解决方案。

虽然,按道理来说,系统时间进行重置之后,一些应用程序的行为出现异常是合乎情理,并且是可以被理解并接受的,最重要的是这样的问题都可以通过重新启动操作系统来解决(微软大哥解决问题之道),但是,对于软件开发人员来说,应该尽量避免非必要的重启。对自己严格要求点儿似乎没什么过错!?

对绝对时间的依赖似乎不怎么容易摆脱,但是我们的应用程序又有多少是严格依赖于系统的绝对时间呢?很多时候,我们只要求能够求出时间间隔就可以了。时间间隔实际上是可以抛开绝对时间求得的,我们可以采用相对于某个时间点的相对时钟来计时,比如说系统启动时间。

自然地,我们就想到了proc伪文件系统下的/proc/uptime文件。通过读这个文件,我们能够获得相对于系统启动时刻的相对时间,其精度为百分之一秒:

[xiaosuo@Ulard-iolo ~]$ cat /proc/uptime
4057840.13 3326432.09

读/proc/uptime简单易行,也适合shell操作,但是只为了一个简单的相对时间就进行三次系统调用(open, read, close)和一次字符串解析,这样的复杂度显然不能满足吹毛求疵的我这种人的非礼要求。

联想到Linux内核空间的精度为(1/HZ)秒的计时变量jiffies,如果有哪个系统调用把它导到用户空间,其效率可见是比较高的,再次扒到了系统调用times:

       #include <sys/times.h>

       clock_t times(struct tms *buf);


times的返回值是相对于某个固定时刻的时间。这个固定时刻,在2.4内核及其之前是系统启动,以后就改成了系统启动((2^32/HZ) - 300)秒之前(这个对jiffies初始值的改动是为了使Linux内核能够尽快地暴露有关jiffies变量回卷的bug)。所以,应用程序不要依赖于这个开始时刻,如果非要依赖,可以通过其他的方式先得到系统的启动时间,然后与其做差值,求得偏移量,以后就能参考这个偏差求得系统的启动时间。这个函数的返回值clock_t的单位为(1/sysconf(_SC_CLK_TCK);)秒(sysconf(_SC_CLK_TCK)通常为100),并且clock_t可能溢出(在2.6内核的Linux系统上,系统启动5分钟就会溢出),所以需要特别小心。

times虽然高效,但是他的精度还是略显不够,所以我继续挖掘。最终找到了clock_gettime这个系统调用:

       #include <time.h>

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


clk_id为CLOCK_MONOTONIC的单调时钟能够满足我们的需求,并且它的精度一般都会很高,略微地浏览了一遍它的内核实现,也较为轻量,可谓完美!

以上介绍的三种获得相对时间的方法的详细用法,还请各位在需要的时候去翻看其手册页,具体应用我就不列举了,因为,要洗洗睡了!:)
阅读(3571) | 评论(3) | 转发(0) |
0

上一篇:splice系列系统调用

下一篇:无题

给主人留下些什么吧!~~

xiaosuo2008-04-02 10:24:19

如果对uptime的时间精度(精确到妙)要求不高,还可以通过Linux特有的系统调用sysinfo获得。

chinaunix网友2008-03-28 10:10:53

good, thanks QQ:6232061

BenBear2008-03-18 08:44:52

顶~~