Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2117393
  • 博文数量: 374
  • 博客积分: 7276
  • 博客等级: 少将
  • 技术积分: 5668
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-06 16:35
文章分类

全部博文(374)

文章存档

2013年(23)

2012年(153)

2011年(198)

分类: LINUX

2012-04-20 14:05:13

1.  低精度计时

sleep 和 usleep :

sleep(int x) 系统调用,让进程等待x秒钟。其精度以秒为单位的。

usleep( int x)系统调用,让进程等待x 纳秒,但实际其精度一般是10ms,再低的达不到。

这两个函数的优点是简单。

 

select:

int select(intnfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,

               struct timeval *timeout);

可 以通过select调用,传递timeout时间,来获取和sleep或usleep类似的效果。select函数调用比sleep和usleep复杂得 多,有人自作聪明的认为sleep/usleep精度不够,使用select替代usleep。可惜select的精度和usleep一样,都是在 10ms这个级别的。

 

2. 高精度计时

2.1 原始办法 (忙等)

    struct timespec now ;

   clock_gettime(CLOCK_REALTIME,&now);

   now.tv_sec += 需要等待的秒数;

   now.tv_nsec +=需要等待的纳妙数;

    while(1){

     struct timespec t;

      clock_gettime(CLOCK_REALTIME, &t);

      if(t.tv_sec > now.tv_sec || t.tv_sec == now.tv_sec && t.tv_nsec > now.tv_nsec)break;

    }

2.2 计时器 (timer_create)

void ticker2(union sigval v)

{

   //v.sival_int为下面的tmcreate2传递的id

   时钟处理函数

}

 

int tmcreate2(int   microsec,   int   id)
{
  timer_t tid;
  struct sigevent se;
  struct itimerspec ts, ots;
  memset(&se,0,sizeof(se));
  se.sigev_notify = SIGEV_THREAD;
  se.sigev_notify_function = ticker2;
  se.sigev_value.sival_int = id;
  if(timer_create(CLOCK_MONOTONIC, &se, &tid) < 0){
      perror("timer_creat");
      return -1;
  }
  ts.it_value.tv_sec = 3;
  ts.it_value.tv_nsec = 0;
  ts.it_interval.tv_sec = 0;
  ts.it_interval.tv_nsec = microsec*1000; //纳妙级
  if(timer_settime(tid, TIMER_ABSTIME, &ts, &ots)   <   0){
    perror("timer_settime");
    return -1;
  }
  return 0;
}

编译时需要加-lrt:gcc xxx.c -lrt

timer_create实际上调用的是rdrtc指令,因此精度和CPU的频率有关。这应该是应用层所能达到最高级别精度的时钟了。其缺点是不够灵活,定时器一旦创建就定期的调用处理函数,不能像usleep需要的时候调用一次,等待一次就结束了。

 

2.3  pthread_cond_timedwait

实验表明这个函数的精度可以达到微妙级以下,估计和timer_create的级别差别不多了。

int pthread_cond_timedwait(pthread_cond_t *restrictcond,
                                           pthread_mutex_t *restrictmutex,
                                           const struct timespec *restrictabstime);

其中最后一个参数是预期超时时间。

pthread_cond_timedwait一般使用方法为:

struct timespec expire;

clock_gettime(CLOCL_REALTIME,&expire); //获取当前系统时间

expire.tv_sec += 等待秒数;

expire.tv_nsec +=等待纳妙数;

pthread_cond_timedwait(..., &expire);

用pthread_cond_timedwait等待的线程还可以通过pthead_cond_signal唤醒,比较灵活。因此如果对精度有要求的话可以用pthread_cond_timedwait替代usleep函数。

 

内核计时器 (timer)

这个计时器只能在内核模块中使用。其精度为jifferies的精度,一般是1ms(HZ为1000)到5ms(HZ为200)。

 总的来说,timer的用法还是很简单的。主要需要定义一个timer_list变量timer、
先初始化timer
init_timer(&timer);
then 对timer的相关参数赋值:
timer.function = fun;
timer.expires = jiffies + TIMER_DELAY;

add_timer(&timer);
在定时器时间到的时候,会执行fun,如果继续定时,可以通过
在fun中执行
mod_timer(&timer, jiffies + TIMER_DELAY);

在不需要的时候通过调用
del_timer(&timer);
删除定时器。

 

除了这个定时器外,另有hrtimer,精度更高,参考

http://www.ibm.com/developerworks/linux/library/l-timers-list/index.html
阅读(5695) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~