当前位置: 首页 > news >正文

Linux 定时器

Linux下实现定时器Timer的几种方法

标签: timerlinuxsignalnull多线程struct
 分类:
 
Linux(57) 

定时器Timer应用场景非常广泛,在Linux下,有以下几种方法:

1,使用sleep()和usleep()

其中sleep精度是1秒,usleep精度是1微妙,具体代码就不写了。使用这种方法缺点比较明显,在Linux系统中,sleep类函数不能保证精度,尤其在系统负载比较大时,sleep一般都会有超时现象。

2,使用信号量SIGALRM + alarm()

这种方式的精度能达到1秒,其中利用了*nix系统的信号量机制,首先注册信号量SIGALRM处理函数,调用alarm(),设置定时长度,代码如下:

 

[cpp]  view plain  copy

Flash Content!

Click to Activate Flash

  1. #include <stdio.h>  
  2. #include <signal.h>  
  3.   
  4. void timer(int sig)  
  5. {  
  6.         if(SIGALRM == sig)  
  7.         {  
  8.                 printf("timer\n");  
  9.                 alarm(1);       //we contimue set the timer  
  10.         }  
  11.   
  12.         return ;  
  13. }  
  14.   
  15. int main()  
  16. {  
  17.         signal(SIGALRM, timer); //relate the signal and function  
  18.   
  19.         alarm(1);       //trigger the timer  
  20.   
  21.         getchar();  
  22.   
  23.         return 0;  
  24. }  
alarm方式虽然很好,但是无法首先低于1秒的精度。

 

3,使用RTC机制

RTC机制利用系统硬件提供的Real Time Clock机制,通过读取RTC硬件/dev/rtc,通过ioctl()设置RTC频率,代码如下:

 

[cpp]  view plain  copy

Flash Content!

Click to Activate Flash

  1. #include <stdio.h>  
  2. #include <linux/rtc.h>  
  3. #include <sys/ioctl.h>  
  4. #include <sys/time.h>  
  5. #include <sys/types.h>  
  6. #include <fcntl.h>  
  7. #include <unistd.h>  
  8. #include <errno.h>  
  9. #include <stdlib.h>  
  10.   
  11. int main(int argc, char* argv[])  
  12. {  
  13.         unsigned long i = 0;  
  14.         unsigned long data = 0;  
  15.         int retval = 0;  
  16.         int fd = open ("/dev/rtc", O_RDONLY);  
  17.   
  18.         if(fd < 0)  
  19.         {  
  20.                 perror("open");  
  21.                 exit(errno);  
  22.         }  
  23.   
  24.         /*Set the freq as 4Hz*/  
  25.         if(ioctl(fd, RTC_IRQP_SET, 1) < 0)  
  26.         {  
  27.                 perror("ioctl(RTC_IRQP_SET)");  
  28.                 close(fd);  
  29.                 exit(errno);  
  30.         }  
  31.         /* Enable periodic interrupts */  
  32.         if(ioctl(fd, RTC_PIE_ON, 0) < 0)  
  33.         {  
  34.                 perror("ioctl(RTC_PIE_ON)");  
  35.                 close(fd);  
  36.                 exit(errno);  
  37.         }  
  38.   
  39.         for(i = 0; i < 100; i++)  
  40.         {  
  41.                 if(read(fd, &data, sizeof(unsigned long)) < 0)  
  42.                 {  
  43.                         perror("read");  
  44.                         close(fd);  
  45.                         exit(errno);  
  46.   
  47.                 }  
  48.                 printf("timer\n");  
  49.         }  
  50.         /* Disable periodic interrupts */  
  51.         ioctl(fd, RTC_PIE_OFF, 0);  
  52.         close(fd);  
  53.   
  54.         return 0;  
  55. }  
这种方式比较方便,利用了系统硬件提供的RTC,精度可调,而且非常高。
4,使用select()

 

这种方法在看APUE神书时候看到的,方法比较冷门,通过使用select(),来设置定时器;原理利用select()方法的第5个参数,第一个参数设置为0,三个文件描述符集都设置为NULL,第5个参数为时间结构体,代码如下:

 

[cpp]  view plain  copy

Flash Content!

Click to Activate Flash

  1. #include <sys/time.h>  
  2. #include <sys/select.h>  
  3. #include <time.h>  
  4. #include <stdio.h>  
  5.   
  6. /*seconds: the seconds; mseconds: the micro seconds*/  
  7. void setTimer(int seconds, int mseconds)  
  8. {  
  9.         struct timeval temp;  
  10.   
  11.         temp.tv_sec = seconds;  
  12.         temp.tv_usec = mseconds;  
  13.   
  14.         select(0, NULL, NULL, NULL, &temp);  
  15.         printf("timer\n");  
  16.   
  17.         return ;  
  18. }  
  19.   
  20. int main()  
  21. {  
  22.         int i;  
  23.   
  24.         for(i = 0 ; i < 100; i++)  
  25.                 setTimer(1, 0);  
  26.   
  27.         return 0;  
  28. }  
这种方法精度能够达到微妙级别,网上有很多基于select()的多线程定时器,说明select()稳定性还是非常好。

 

 

总结:如果对系统要求比较低,可以考虑使用简单的sleep(),毕竟一行代码就能解决;如果系统对精度要求比较高,则可以考虑RTC机制和select()机制

相关文章:

  • HBase源码分析之HRegion上compact流程分析(一)
  • [iOS]如何删除工程里面用cocoapods导入的第三方库
  • KVC和KVO
  • @synthesize和@dynamic分别有什么作用?
  • Shell 中的空值(null value)和不存在是不一样的。
  • 提高自己应用性能的总结架构篇
  • 什么是端口映射
  • java中使用poi实现导入Excel
  • asp.net预定义的HttpModule
  • 20160309高项作业
  • nginx服务器绑定域名和设置根目录的方法
  • 不懂编程的运维人员到底还能走多远?
  • 经典SQL语句大全(数据开发篇)
  • 【Linux】一张图让你读懂Linux内核运行原理
  • nginx负载均衡实现tomcat集群
  • android 一些 utils
  • chrome扩展demo1-小时钟
  • CSS中外联样式表代表的含义
  • Docker入门(二) - Dockerfile
  • ES6系列(二)变量的解构赋值
  • python_bomb----数据类型总结
  • Python爬虫--- 1.3 BS4库的解析器
  • scrapy学习之路4(itemloder的使用)
  • 百度地图API标注+时间轴组件
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 技术:超级实用的电脑小技巧
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 漂亮刷新控件-iOS
  • 为什么要用IPython/Jupyter?
  • 线性表及其算法(java实现)
  • 译自由幺半群
  • 最简单的无缝轮播
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • Spring Batch JSON 支持
  • 我们雇佣了一只大猴子...
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • (1)SpringCloud 整合Python
  • (13):Silverlight 2 数据与通信之WebRequest
  • (14)Hive调优——合并小文件
  • (pojstep1.1.2)2654(直叙式模拟)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (七)Java对象在Hibernate持久化层的状态
  • (四)c52学习之旅-流水LED灯
  • (一一四)第九章编程练习
  • (转)可以带来幸福的一本书
  • (转)重识new
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • ***原理与防范
  • .bat批处理(六):替换字符串中匹配的子串
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑