1-Linux time system

题图:nipic

Linux time system

Linux中跟时间有关的函数变量有很多,但是对开发者来说无非就是用了计时/延时/挂起/获取时间等,下面列出自己所使用过的一些时间接口,供大家理解使用。

1.jiffies


在内核代码中,到处充斥着jiffies变量,jiffies在include/linux/jiffies.h中定义,在linux启动的时候会将jiffies清0,当系统完成对时钟中断的初始化后,在每个时钟滴答时jiffies都会被加1,所以在驱动程序开发过程中,使用jiffies变量就已足够所有基于jieffies的时间度量任务。

jiffies的使用通常要配合着宏HZ,宏HZ的定义位于.confg,一般都将其设置为1000,1秒1000次即1ms。
例:

time1 = jiffies + 2 * HZ;则time1表示未来的2秒;
time2 = jiffies + 3 * HZ/1000;则time2表示未来的3毫秒;

在jiffies.h还为我们提供了很多接口函数,主要有两类,一类为时间的比较,一类为时间的转化。 下面进行简单说明举例:
1、时间的比较

time_after(a,b);        //如果时间点a在时间点b之后,则返回1
time_before(a,b);       //如果时间点a在时间点b之前,则返回1
time_after_eq(a,b);     //如果时间点a在时间点b之后或等于b,则返回1
time_before_eq(a,b);    //如果时间点a在时间点b之前或等于b,则返回1
time_in_range(a,b,c);   //如果时间点a在时间点b和c之间或等于b或c,则返回1

例:

int time_test()
{
    unsigned long timeout = jiffies + 2 * HZ/1000;  //2ms
    do_time_task();
    if(time_after(jiffies,timeout))    //如果do_time_task()函数执行超过2ms,则成立
        return 1;
    return 0;
}

2.时间转化
为了方便理解,我们需要将jiffies转化成比较直观的毫秒ms或者是微妙us等形式,jiffies.h里面一个了一些比较直观的转化函数,其实现函数在kernel/time.c里面 如:

unsigned int jiffies_to_msecs(const unsigned long j);
unsigned int jiffies_to_usecs(const unsigned long j);
unsigned long msecs_to_jiffie(const unsigned int m);
unsigned long usecs_to_jiffie(const unsigned int u);

2.do_gettimeofday


当我们需要得到某一段代码所执行的时间是多少,可以使用do_gettimeofday函数,该函数定义在kernel/time/timekeeping.c中,申明在include/linux/time.h中,do_gettimeofday函数是在内核的函数,如果在应用层实现该这个函数则使用gettimeofday,包含sys/time.h即可,使用方法与do_gettimeofday一样。

举个简单的例子:

int gettimeofday_test()
{
    struct timeval tv_start;
    struct timeval tv_end;
    float timeuse;
    
    gettimeofday(&tv_start, NULL);
    do_gettimeofday_task();
    gettimeofday(&tv_end, NULL);
    
    timeuse = 1000000*(tv_end.tv_sec - tv_start.tv_sec) + tv_end.tv_usec - tv_start.tv_usec;
    timeuse /= 1000;
    printf("Time-consuming: %f ms\n",  timeuse);

    return 0;
}

3.delay


delay函数为死等待,这种函数只能用在短延时上,如微妙甚至纳秒等级的 Linux内核提供了如下短延时接口函数,位于include/linux/delay.h中

void mdelay(usigned long msecs); 
void udelay(usigned long usecs); 
void ndelay(usigned long nsecs);

4.sleep


上面的短延时为忙等待,当为长延时不能为忙等待,需要将任务挂起,这是我们可以使用sleep函数 在kernel/timer.c里面有实现了msleep()函数,也在include/linux/delay.h中申明,其原型如下,

sleep也是我们在写shell脚本时比较经常使用的延时、循环执行命令,直接调用即可使用。

5.内核定时器timer


如果希望在内核中以一定的时间间隔来执行执行某项任务,如:每隔一秒查询一次button的状态,可以使用内核定时器来实现。内核中已经为我们提供了定时器数据结构timer_list,和定时器的接口函数,位于include/linux/timer.h中。

定时器timer的实现步骤就两步:

  • 初始化定时器,设置定时器的触发时间,指定该定时器的回调函数。
  • 实现定时器回调函数,如果需要循环执行,则需要在该定时器的回调函数中重新启动该定时器。

举个简单的例子:

#define TIMER_FUNC(_fn)  void _fn(unsigned long timer_arg)
#define TIMER_INIT(_osdev, _timer, _fn, _arg)        \
do {                                                 \
        init_timer(_timer);                          \
        (_timer)->function = (_fn);                  \
        (_timer)->data = (unsigned long)(_arg);      \
} while (0)
#define TIMER_SET(_timer, _ms)  mod_timer(_timer, jiffies + ((_ms)*HZ)/1000)

struct timer_list os_timer_test; 

static TIMER_FUNC(timer_test_func)
{
    do_timer_func();
    TIMER_SET(&os_timer_test, 1000);   //重新设置该定时器
}

int timer_test()
{
    TIMER_INIT(NULL, &os_timer_test, timer_test_func, &os_timer_test);    //初始化定时器,绑定回调函数
    TIMER_SET(&os_timer_test, 1000);   //1s
    return 0;
}

6.系统时间date


date主要用来显示和设定系统的日期与时间,通常会在shell中使用到data命令

1.data的显示

最直接的方式即输入date,如下:

# date 
Thu Dec 15 14:28:19 GMT 2016

这种方式会将信息以一定的格式显示出来,星期、月份、日期、时:分:秒、时区、年份
如果我们需要得到更具体的信息可以通过"data +%$"来获取,如:

# date +%H    //小时
14
# date +%m    //月份
12
# date +%y    //年份
16

具体指令如下:

命令 含义
%H 小时(00..23)
%I 小时(01..12)
%k 小时(0..23)
%l 小时(1..12)
%M 分钟(00..59)
%p 显示本地 AM 或 PM
%r 直接显示时间 (12 小时制,格式为 h : m : s [AP]M)
%s 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
%S 秒(00..61)
%T 直接显示时间 (24 小时制)
%X 相当于 %H:%M:%S
%Z 显示时区
%a 星期几 (Sun..Sat)
%A 星期几 (Sunday..Saturday)
%b 月份 (Jan..Dec)
%B 月份 (January..December)
%c 直接显示日期与时间
%d 日 (01..31)
%D 直接显示日期 (mm/dd/yy)
%h 同 %b
%j 一年中的第几天 (001..366)
%m 月份 (01..12)
%U 一年中的第几周 (00..53) (以 Sunday 为一周的第一天的情形)
%w 一周中的第几天 (0..6)
%W 一年中的第几周 (00..53) (以 Monday 为一周的第一天的情形)
%x 直接显示日期 (mm/dd/yy)
%y 年份的最后两位数字 (00.99)
%Y 完整年份 (0000..9999)

2.data的设置

既然读取到了时钟发现错误时就需要修改,修改的方式有很多,这边就不想弄的那么复杂,用一个最直观简单的格式,如下:

# date -s "2016-12-15 14:43:33"
Thu Dec 15 14:43:33 GMT 2016

7.RTC时钟hwclock


linux系统时钟有两个,一个是硬件时钟,一般就是RTC时钟,另一个是系统时钟,即上面使用date时得到的信息,它是linux系统Kernel时间。当Linux启动时,系统Kernel会去读取硬件时钟的设置,然后系统时钟就会独立于硬件运作。

硬件时钟可以通过hwclock来获取,如下:

# hwclock 
Thu Dec 15 11:12:07 2016  0.000000 seconds

当我们修改了系统时钟后,想将系统时间同步到硬件时钟可以通过hwclock -w命令实现,如下:

# date -s "2016-12-15 15:40:00"
Thu Dec 15 15:40:00 GMT 2016
# hwclock 
Thu Dec 15 11:24:25 2016  0.000000 seconds
# hwclock -w
# hwclock 
Thu Dec 15 15:40:23 2016  0.000000 seconds

busybox里面也实现从硬件时钟同步到系统时钟的命令hwclock -s,但这个指令一般很少用,因为kernel一启动系统时钟就是读取硬件的时钟,所以两则已经相等了,我们发现系统时钟不对时,则会去修改系统时钟再同步到硬件时钟。

Linux time system的分析就到这边,有感悟时会持续会更新。

注:以上内容都是本人在学习过程积累的一些心得,难免会有参考到其他文章的一些知识,如有侵权,请及时通知我,我将及时删除或标注内容出处,如有错误之处也请指出,进行探讨学习。文章只是起一个引导作用,详细的数据解析内容还请查看Linux相关教程,感谢您的查阅。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,128评论 2 34
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,401评论 25 707
  • 1.命令格式:ifconfig [网络设备] [参数] 2.命令功能: ifconfig 命令用来查看和配置网络设...
    Nuuuu阅读 3,695评论 0 12
  • Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是有意...
    萤火虫de梦阅读 99,125评论 9 467
  • 为了形体更加窈窕聘婷,决定从今天开始,起床之后先做一套《美丽芭蕾》的课程。 还挺累的,明明才16分钟的时间,怎么感...
    水轻扬阅读 120评论 0 1