Linux下的定时器,怎么用。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下的定时器,怎么用。相关的知识,希望对你有一定的参考价值。

是用定时器好?还是新pthread_create一条线程,中间Sleep一个时间间隔好?

参考技术A 时事件,void(*handle)(union sigval v)参数就是处理事件的函数指针。
int omsSetTimer(timer_t *tId,int value,int interval)就是设置定时器。
按你说的,如果要同时起多个定时器,需要定义一个数组timer_t tm[n];int it[n];tm就是定时器结构,it用来记录对应的定时器是否已经使用,使用中的就是1,没用的就是0;
主进程消息来了就从it找一个没用的来omsSetTimer,如果收到终止消息,那omsSetTimer 定时时间为0
int omsTimer(timer_t *tId,int iValue,int iSeconds ,void(*handle)(union sigval v),void * param)

struct sigevent se;
struct itimerspec ts;
memset (&se, 0, sizeof (se));
se.sigev_notify = SIGEV_THREAD;
se.sigev_notify_function = handle;
se.sigev_value.sival_ptr = param;
if (timer_create (CLOCK_REALTIME, &se, tId) < 0)

return -1;

ts.it_value.tv_sec = iValue;
// ts.it_value.tv_sec =3;
//ts.it_value.tv_nsec = (long)(iValue % 1000) * (1000000L);
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = iSeconds;
//ts.it_interval.tv_nsec = (long)(iSeconds % 1000) * (1000000L);
ts.it_interval.tv_nsec = 0;
if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) < 0)

return -1;

return 0;

int omsSetTimer(timer_t *tId,int value,int interval)

struct itimerspec ts;
ts.it_value.tv_sec =value;
//ts.it_value.tv_nsec = (long)(value % 1000) * (1000000L);
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = interval;
//ts.it_interval.tv_nsec = (long)(interval % 1000) * (1000000L);
ts.it_interval.tv_nsec = 0;
if (timer_settime(*tId, TIMER_ABSTIME, &ts, NULL) < 0)

return -1;

return 0;

另外,团IDC网上有许多产品团购,便宜有口碑
参考技术B 数为秒数,在经过指定秒数后,alarm会发出一个SIGALRM信号
singal函数用来绑定信号处理器函数,这里绑定的是timer,被绑定的函数必须固定为返回值void、参数int。
只需要alarm(时间)就设置了,可能由于getchar需要进入中断导致信号被挂起所以没反应吧,可以试试把getchar换成别的东西来延时看看
参考技术C crontab多方便啊!具体命令格式,用法啊,百度上一大堆···

Linux下的hrtimer高精度定时器

本文转载自:http://blog.csdn.net/waverider2012/article/details/38305785

hrtimer高精度定时器的interval由ktime_set(const long secs, const unsigned long nsecs)决定,可做到ns级。此处的例子为5ms interval:

[cpp] view plain copy
 
  1. #include <linux/kernel.h>  
  2. #include <linux/module.h>  
  3. #include <linux/hrtimer.h>  
  4. #include <linux/ktime.h>  
  5.   
  6. MODULE_LICENSE("GPL");  
  7.   
  8. static struct hrtimer hr_timer;  
  9. static struct work_struct wq_hrtimer;    
  10. static ktime_t ktime;  
  11. static unsigned int interval=5000; /* unit: us */  
  12. struct timespec uptimeLast;  
  13.   
  14. static unsigned int count=0;  
  15. #define COUNT_INTERVAL 4000  
  16. unsigned long long diff_tv(struct timespec start, struct timespec end) {  
  17.     return (end.tv_sec-start.tv_sec)*1000000000+(end.tv_nsec-start.tv_nsec);  
  18. }  
  19.   
  20. enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )  
  21. {  
  22.     schedule_work(&wq_hrtimer);   
  23.     return HRTIMER_NORESTART;  
  24. }  
  25.   
  26. static void wq_func_hrtimer(struct work_struct *work)  
  27. {   
  28.     struct timespec uptime;  
  29.   
  30.     hr_timer.function = my_hrtimer_callback;   
  31.     ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );  
  32.     hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL );  
  33.   
  34.     /* print time every COUNT_INTERVAL*interval second*/  
  35.     if(count%COUNT_INTERVAL==0)   
  36.     {  
  37.         do_posix_clock_monotonic_gettime(&uptime);    
  38.         printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns, interval_delay=%lu ns\n",   
  39.             (unsigned long) uptime.tv_sec, uptime.tv_nsec,  
  40.             (unsigned long)(diff_tv(uptimeLast, uptime)-interval*1000*COUNT_INTERVAL) \  
  41.                 /COUNT_INTERVAL);   
  42.         uptimeLast=uptime;  
  43.     }  
  44.     count++;  
  45. }   
  46.   
  47. static int __init module_hrtimer_init( void )  
  48. {  
  49.     struct timespec uptime;   
  50.       
  51.     printk(KERN_INFO"HR Timer module installing\n");  
  52.       
  53.     hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );  
  54.     
  55.     ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );  
  56.     hr_timer.function = my_hrtimer_callback;  
  57.   
  58.     hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );  
  59.   
  60.     do_posix_clock_monotonic_gettime(&uptime);  
  61.     uptimeLast = uptime;  
  62.     printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns\n", (unsigned long) uptime.tv_sec,    
  63.                                         uptime.tv_nsec );   
  64.   
  65.     INIT_WORK(&wq_hrtimer, wq_func_hrtimer);  
  66.     return 0;  
  67. }  
  68.   
  69. static void __exit module_hrtimer_exit( void )  
  70. {  
  71.     int ret;  
  72.   
  73.     ret = hrtimer_cancel( &hr_timer );  
  74.     if (ret)   
  75.         printk("The timer was still in use...\n");  
  76.   
  77.     printk("HR Timer module uninstalling\n");  
  78.     return;  
  79. }  
  80.   
  81. module_init(module_hrtimer_init);  
  82. module_exit(module_hrtimer_exit);  

 

如果在my_hrtimer_callback()里面直接返回HRTIMER_RESTART会导致立即重新进入my_hrtimer_callback()。这时shell对输入没有任何响应。

所以为了解决这个问题,创建了一个work queue,由my_hrtimer_callback() enqueue这个工作队列。在work queue的处理函数里面重启hrtimer。

但是这样带来的负面影响是进入hrtimer_callback和wq_func被调用之间有Linux系统调度引入的延迟,导致interval出现误差。经过实测,在ZC706缺省配置下,这个延迟大约是17.5us (hrtimer interval为5ms,每20秒计算一次interval误差)。

[plain] view plain copy
 
    1. [email protected]:~/nfs/hrtimer# insmod hrtimer.ko  
    2. HR Timer module installing  
    3. hrtimer:    2900 sec, 993366078 ns  
    4. hrtimer:    2900 sec, 998395278 ns, interval_delay=369966 ns  
    5. hrtimer:    2921 sec,  69525447 ns, interval_delay=17782 ns  
    6. hrtimer:    2941 sec, 139764655 ns, interval_delay=17559 ns  
    7. hrtimer:    2961 sec, 210029519 ns, interval_delay=17566 ns  
    8. hrtimer:    2981 sec, 280465631 ns, interval_delay=17609 ns  
    9. hrtimer:    3001 sec, 350677038 ns, interval_delay=17552 ns  
    10. hrtimer:    3021 sec, 420625114 ns, interval_delay=17487 ns  
    11. hrtimer:    3041 sec, 490744847 ns, interval_delay=17529 ns 

以上是关于Linux下的定时器,怎么用。的主要内容,如果未能解决你的问题,请参考以下文章

如何写个脚本将Linux目录下的几个文件夹定时复制

Linux下的定时器

Linux下的hrtimer高精度定时器

Linux下的微秒级别的定时器

Linux下的高精度时间获得与定时器

Linux下的高精度时间获得与定时器