免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7135 | 回复: 7
打印 上一主题 下一主题

[C] 求:C语言实现Linux内核定时器 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-28 15:35 |只看该作者 |倒序浏览
本帖最后由 hxh88888888 于 2010-05-28 15:53 编辑

高手请指教C语言如何实现Linux内核定时器,最好有实现代码,比较急,希望能指教!

我是在应用层使用的定时器,不知道可以使用内核态的定时器吗?

论坛徽章:
0
2 [报告]
发表于 2010-05-28 16:01 |只看该作者
setitimer

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2010-05-28 17:30 |只看该作者
内核态就有定时器啊。

论坛徽章:
0
4 [报告]
发表于 2010-05-28 17:53 |只看该作者
setitimer
TMBest 发表于 2010-05-28 16:01


正解

论坛徽章:
0
5 [报告]
发表于 2010-05-28 18:15 |只看该作者
回复 2# TMBest


    使用这个和使用usleep的效果差不多,达不到如3ms的间隔时间

论坛徽章:
0
6 [报告]
发表于 2010-05-28 23:51 |只看该作者
如果你对精度要求非常高的话,先在BIOS里关掉CPU节能,以免主频变化。然后用rdtsc取CPU时钟周期来记时,就可以到微秒以下的精度。

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
7 [报告]
发表于 2010-05-29 01:54 |只看该作者
本帖最后由 vbs100 于 2010-05-29 01:56 编辑

这有一篇介绍内核定时器设计的文章
http://lwn.net/Articles/156329/
它用了一个叫时间轮timer wheel的算法,插入、删除、超时的复杂度都是O(1)的
如果你比较急就用 libevent的定时器吧 用最小堆实现的 插入时O(log N),删除、超时也都是O(1)的

论坛徽章:
0
8 [报告]
发表于 2010-05-29 08:17 |只看该作者
回复  TMBest


    使用这个和使用usleep的效果差不多,达不到如3ms的间隔时间
hxh88888888 发表于 2010-05-28 18:15

settimer和usleep的实现完全不同,settimer是让内核定期通过中断来通知的,每次中断时进程基本上就会被调度到,usleep是进程自己控制的,只有再被调度到并且时间够了之后才会被唤醒,所以usleep不准确,但settimer准确,我最近在项目中正好也用到settimer了,在我的项目中测试后是基本准确的,我的项目要求精确度是1ms。可以看一下我测试的一些经验:


 因为项目的需要,需要精度为1ms的定时器,对于PC 机中的时间是由三种时钟硬件提供的,而这些时钟硬件又都基于固定频率的晶体振荡器来提供时钟方波信号输入。这三种时钟硬件是:实时时钟(Real Time Clock,RTC );可编程间隔定时器(Programmable Interval Timer ,PIT );时间戳计数器(Time Stamp Counter,TSC).在用户空间,windows下提供的API有:SetTImer,linux下提供的API有:rtc和settimer(也有其他的)。linux下的这两者都是通过中断来实现的,只是rtc是通过文件描述符来通知的,settimer是利用信号来通知的。

    rtc基于文件描述符就意味着我们需要在单独的线程中编写一个死循环来检查文件描述符是否可读,然而线程调度的初始时间间隔是20ms,意味着只有等到线程被调度到时才可以测试文件描述符是否可读,这样的话就不准确了,达不到1ms的时间精度,还好经过测试事实不是这样的,用rtc的话可以基本精确到1ms。据我猜测是这样的:因为rtc本身也是通过中断来通知进程的,当进程被rtc通知时就尽量去调度正阻塞在rtc对应的文件描述符的那个线程,这样就不会因为线程调度时间间隔太长而导致rtc定时器不精确,经过实测,2个线程,64HZ的rtc通知58w次,仅有2次有问题,说明利用rtc做定时器是基本准确的,在项目中使用时也达到了较好的效果。

    用settimer做定时器一样可以达到精确的效果,而且settimer是通过信号来通知的,意味着不需要另外开一个线程来做定时器,在当前线程即可做定时器。看起来应该是比rtc更好一些,但由于信号会中断低速系统调用,会导致其他部分的逻辑破坏,当然可以用SA_RESTART来保证低速系统调用被中断唤醒后会自动重启,但nanosleep不会(当然也有其他方法解决此问题),而我们项目中正好用到此系统调用,故而采用了rtc。

    最终还是采用了settimer,因为在pc机上rtc只能让单进程使用,崩溃!经测试11.6w次,仅有一次为22ms,其余皆正常,可认为settimer比较准确,完全符合我的要求。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP