POSIX:TMR间隔定时器

1、int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)

   进程可以通过调用timer_create()创建特定的定时器,定时器是每个进程自己的,不是在fork时继承的。timer_create的参数clock_id说明定时器是基于哪个时钟的,*timerid装载的是被创建的定时器的IDtimer_create函数创建了定时器,并将他的ID放入timerid指向的位置中。参数evp指定了定时器到期要产生的异步通知。如果evpNULL,那么定时器到期会产生默认的信号,对CLOCK_REALTIMER来说,默认信号就是SIGALRM。对那些定时器到期时要产生除默认信号之外的其它信号的定时器来说,程序必须将evp->sigev_signo设置为期望的信号码。struct sigevent 结构中的成员evp->sigev_notify说明了定时器到期时应该采取的行动。通常,这个成员的值为SIGEV_SIGNAL,这个值说明在定时器到期时,会产生一个信号。程序可以将成员evp->sigev_notify设为SIGEV_NONE来防止定时器到期时产生信号。

 

如果几个定时器产生了同一个信号,处理程序可以用evp->sigev_value来区分是哪个定时器产生了信号。要实现这种功能,程序必须在为信号安装处理程序时,使用struct sigaction的成员sa_flags中的标志符SA_SIGINFO

clock_id的取值为以下:

CLOCK_REALTIME :Systemwide realtime clock.

CLOCK_MONOTONIC:Represents monotonic time. Cannot be set.

CLOCK_PROCESS_CPUTIME_ID :High resolution per-process timer.

CLOCK_THREAD_CPUTIME_ID :Thread-specific timer.

CLOCK_REALTIME_HR :High resolution version of CLOCK_REALTIME.

CLOCK_MONOTONIC_HR :High resolution version of CLOCK_MONOTONIC.

 

struct sigevent

{

int sigev_notify; //notification type

int sigev_signo; //signal number

union sigval   sigev_value; //signal value

void (*sigev_notify_function)(union sigval);

pthread_attr_t *sigev_notify_attributes;

}

union sigval

{

int sival_int; //integer value

void *sival_ptr; //pointer value

}

通过将evp->sigev_notify设定为如下值来定制定时器到期后的行为:

l         SIGEV_SIGNAL: 发送由evp->sigev_sino指定的信号到调用进程,evp->sigev_value的值将被作为siginfo_t结构体中si_value的值。

l         SIGEV_NONE:什么都不做,只提供通过timer_gettimetimer_getoverrun查询超时信息。

l         SIGEV_THREAD: evp->sigev_notification_attributes为线程属性创建一个线程,在新建的线程内部以evp->sigev_value为参数调用evp->sigev_notification_function

 

2、int timer_delete(timer_t timerid);

删除IDtimeridPOSIX:TMR定时器。

3、int timer_settime(timer_t timerid,int flags,const struct itimerspec *value,struct itimerspec *ovalue);

struct     itimerspec   
{  
 
       struct     timespec   it_interval; //
定时器周期值
       struct     timespec   it_value;     //
定时器到期值
};  
 

      timer_settime负责启动或停止timer_create创建的定时器。参数flag说明定时器使用的是相对时间还是绝对时间。相对时间与POSIX:XSI定时器使用的策略类似,而绝对时间的精确度更高。参数vaule指向的值来设置timerid指定的定时器。如果ovalue不为NULLtimer_settime就将定时器以前的值放在ovalue指定的位置上。如果定时器正在运行,那么*ovalue的成员it_value非零,并包含了定时器到期之前剩余的时间。

TIMER_ABSTIME表示绝对时间;
如果flag没有设定为TIMER_ABSTIME,则定时器从调用开始在it_value内超时;即value->it_value代表计时器第一次超时的时间。
如果设定为TIMER_ABSTIME,该函数表现为时间直到下一次超时被设定为it_value指定的绝对时间和与timerid相联的时钟值的差值。如果已经到了it_value指定的值,那么超时后的处理就会立即执行。

定时器的再装由valueit_interval成员值来设定。



4、int timer_gettime(timer_t timerid,struct itimerspec *value);

获得一个活动定时器的剩余时间。

int timer_getoverrun(timer_t timerid);

       有可能一个定时器到期了,而同一定时器上一次到期时产生的信号还处于挂起状态。在这种情况下,其中的一个信号可能会丢失。这就是定时器超限。程序可以通过调用timer_getoverrun来确定一个特定的定时器出现这种超限的次数。定时器超限只能发生在同一个定时器产生的信号上。由多个定时器,甚至是那些使用相同的时钟和信号的定时器,所产生的信号都会排队而不会丢失。


5、api接口定义

timer_t g_timerid = 0;

/****************************************************************************

 功    能:   定时器回调函数
 输入参数: v:sigev_value作为入参
 输出参数:


 返 回 值:   无
****************************************************************************/
static void timer_thread(union sigval v)  
{  
debug(DBG_DEBUG, "timer_thread\n");

/****************************************************************************
 功    能:   定时器创建
  定时时间到调用回调函数timer_thread
 输入参数:
 输出参数:无


 返 回 值:   0:成功 -1:失败
****************************************************************************/
int InitTimer(void)

static int ITimerFlag = 0;
    struct sigevent evp;  

debug(DBG_DEBUG, "timer_create start\n");
if (! ITimerFlag) {
   memset(&evp, 0, sizeof(struct sigevent));       //清零初始化  
debug(DBG_DEBUG, "timer_create start\n");
   evp.sigev_value.sival_int = getpid();            //也是标识定时器的,这和timerid有什么区别?回调函数可以获得  
   evp.sigev_notify = SIGEV_THREAD;            //线程通知的方式,派驻新线程  
   evp.sigev_notify_function = timer_thread;       //线程函数地址  

   if (timer_create(CLOCK_REALTIME, &evp, &g_timerid) == -1)  
   {  
debug(DBG_DEBUG, "timer_create Failed\n");
       return -1;  
   } 
ITimerFlag = 1;
}

return 0;
}


/****************************************************************************
 功    能:   定时器启动
 输入参数: sec:秒数
  usec:微妙
 输出参数:无


 返 回 值:   0:成功 -1:失败
****************************************************************************/
int Api_BaseStartTimer(time_t sec, suseconds_t usec)
{
struct itimerspec value;

if (g_timerid == 0)
{
debug(DBG_DEBUG, "timerid Failed\n");
return -1;
}
debug(DBG_DEBUG, "sec = %d, usec = %d\n", sec, usec);
// 启动定时器,启动后立即执行一次,以后按照间隔来
    value.it_interval.tv_sec  = sec;  
    value.it_interval.tv_nsec = usec;  
    value.it_value.tv_sec     = 0;  
    value.it_value.tv_nsec    = 10;//切记要加上这个小时间,不然定时器无法生效。设置成0就不生效了!
if (timer_settime(g_timerid, 0, &value, NULL) == -1)  
    {  
    debug(DBG_DEBUG, "fail to timer_settime\n");
        return -1;
    } 

    return 0;
}


/****************************************************************************
 功    能:   停止定时器
 输入参数:
 输出参数:无


 返 回 值:   0:成功 -1:失败
****************************************************************************/
int StopTimer(void)
{
struct itimerspec value;

if (g_timerid == 0){
debug(DBG_DEBUG, "fail to timer_settime\n");
return -1;
}
debug(DBG_DEBUG, "StopTimer \n");
// 启动定时器 时间间隔设置成0
//未启动状态
    value.it_interval.tv_sec  = 0;  
    value.it_interval.tv_nsec = 0;  
    value.it_value.tv_sec     = 0;  
    value.it_value.tv_nsec    = 0;

if (timer_settime(g_timerid, 0, &value, NULL) == -1)  
    {  
    debug(DBG_DEBUG, "fail to timer_settime\n");
        return -1;  
    } 

    return 0;

}

/****************************************************************************
 功    能:   删除定时器
 输入参数:
 输出参数:无


 返 回 值:   0:成功 -1:失败
****************************************************************************/

int delettimer(void)

{

int iRet = -1;

iRet = timer_delete(g_timerid);

return iRet;

}

/****************************************************************************
 功    能:   获取定时器剩余时间
 输入参数:
 输出参数:value


 返 回 值:   0:成功 -1:失败
****************************************************************************/

int gettimer(itimerspec *value)

{

int iRet = -1;

iRet = timer_gettime(g_timerid, value);

return iRet;

}

你可能感兴趣的:(定时器,timer_create,timer_settime,timer_delete,timer_gettime)