浅谈linux几种定时函数的使用

2019-10-13 18:19:55刘景俊

在程序开发过程中,我们时不时要用到一些定时器,通常如果时间精度要求不高,可以使用sleep,uslepp函数让进程睡眠一段时间来实现定时,

前者单位为秒(s),后者为微妙(us);但有时候我们又不想让进程睡眠阻塞在哪儿,我们需要进程正常执行,当到达规定的时间时再去执行相应的操作,

在linux下面我们一般使用alarm函数跟setitimer函数来实现定时功能;

下面对这两个函数进行详细分析:

(1)alarm函数

alarm也称为闹钟函数,它可以在进程中设置一个定时器,当定时器指定的时间到时,它向进程发送SIGALRM信号;

alarm函数原型如下:

unsigned int alarm(unsigned int seconds);
//seconds 为指定的秒数

所需头文件
  #include<unistd.h>

函数原型
  unsigned int alarm(unsigned int seconds)

函数参数
  seconds:指定秒数

函数返回值
  成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
  出错:-1

下面是alarm()函数的简单例子:

void sigalrm_fn(int sig)  
 
{ 
  printf("alarm!n"); 
  alarm(2); 
  return; 
} 
 
int main(void) 
 
{ 
  signal(SIGALRM, sigalrm_fn); //后面的函数必须是带int参数的
  alarm(1); 
  while(1)  
  pause(); 
 
}

(2)setitimer()函数

在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了,但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

setitimer()为Linux的API,并非C语言的Standard Library,setitimer()有两个功能,一是指定一段时间后,才执行某个function,二是每间格一段时间就执行某个function;

Linux为每个任务安排了3个内部定时器:

ITIMER_REAL:实时定时器,不管进程在何种模式下运行(甚至在进程被挂起时),它总在计数。定时到达,向进程发送SIGALRM信号。

ITIMER_VIRTUAL:这个不是实时定时器,当进程在用户模式(即程序执行时)计算进程执行的时间。定时到达后向该进程发送SIGVTALRM信号。

ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计数。定时到达产生SIGPROF信号。ITIMER_PROF记录的时间比ITIMER_VIRTUAL多了进程调度所花的时间。

定时器在初始化是,被赋予一个初始值,随时间递减,递减至0后发出信号,同时恢复初始值。在任务中,我们可以一种或者全部三种定时器,但同一时刻同一类型的定时器只能使用一个。

setitimer函数原型如下:

#include <sys/time.h>

    int setitimer(int which, const struct itimerval *new_value,
           struct itimerval *old_value);

 Timer values are defined by the following structures:

      struct itimerval {
        struct timeval it_interval; /* next value */
        struct timeval it_value;  /* current value */
      };

      struct timeval {
        time_t   tv_sec;     /* seconds */
        suseconds_t tv_usec;    /* microseconds */
      };