setitimer函数功能介绍编辑
在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了,但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。
setitimer函数参数介绍编辑
int setitimer(int which, const structitimerval *value, struct itimerval *ovalue);
which为定时器类型,setitimer支持3种类型的定时器:
ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
setitimer()第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。
setitimer()调用成功返回0,否则返回-1。
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。
tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。
ovalue用来保存先前的值,常设为NULL。
如果是以setitimer提供的定时器来休眠,只需阻塞等待定时器信号就可以。
实例:过滤POWER_OFF_ON,要求每间隔500ms启动一次定时器,定时器时间到后再执行定时器里面的动作(播放暂停)
(1)定时器定义:
void set_power_off_on_send_timer(inttv_sec,int tv_usec);
/*
* 开始链接POWER_OFF_ON发送的处理函数
*/
void power_off_on_send_timer_func(int sig) /* 定时事件代码 */
{
// 定时器溢出,如果此时用户点击车机POWER_OFF_ON硬按键,则会向手机发送播放暂停消息
if(flag_power_off_on_timer > 0)
{
PhoneLinkPlayPause(TRUE);
}
else if(flag_power_off_on_timer < 0)
{
PhoneLinkPlayPause(FALSE);
}
else
{
//Nothing to do s
}
flag_power_off_on_timer = 0;
}
/*
* 设置定时器时间,设置完后定时器会在指定时间触发power_off_on_send_timer_func 函数
*/
void set_power_off_on_send_timer(int tv_sec,int tv_usec)
{
INFO("set_power_off_on_send_timer \n");
INFO("flag_power_off_on_timer:<%02x>\n",flag_power_off_on_timer);
struct itimerval power_off_on_send_timer_value;
//it_interval指定间隔时间,it_value指定初始定时时间。
power_off_on_send_timer_value.it_value.tv_usec= tv_usec;
power_off_on_send_timer_value.it_value.tv_sec= tv_sec;
power_off_on_send_timer_value.it_interval.tv_usec = tv_usec;
power_off_on_send_timer_value.it_interval.tv_sec = tv_sec;
signal(SIGALRM, power_off_on_send_timer_func); /* 捕获定时信号 */
setitimer(ITIMER_REAL, &power_off_on_send_timer_value, NULL);/* 定时开始*/
}
(2)应用该定时器.
//发送POWER-OFF/ON硬按键定时器的标志位
extern int flag_power_off_on_timer;
int PowerStatusHandle(unsigned charbStatus)
{
printf("PowerStatusHandle(%d)\n", bStatus);
//printf("flag_power_off_on_timer:<%02x>\n",flag_power_off_on_timer);
unsigned char src = GetCurSource();
static unsigned char starttimerFlag = FALSE;
//printf("power status ==%d\n",bStatus);
if(SWITCH_OFF== bStatus)//关屏
{
switch(src)
{
case SOURCE_AUDIO_PLAYER:
MusicBtnPause();
break;
case SOURCE_VIDEO_PLAYER:{
VideoBtnPause();
}
break;
case SOURCE_IPOD:
IpodPlayCtrlPlayPause(IPODPAUSE);
break;
case SOURCE_SMARTPHONE:
//为避免用户频繁的点击车机的POWER_ON_OFF按键,利用定时器过滤POWER_ON_OFF硬按键消息
if(starttimerFlag == FALSE)
{
starttimerFlag = TRUE;
set_power_off_on_send_timer(0,5*1000*100);
PhoneLinkPlayPause(FALSE);
}
else
{
flag_power_off_on_timer--;
}
break;
}
}
else if(SWITCH_ON== bStatus)//开屏
{
switch(src)
{
case SOURCE_AUDIO_PLAYER:
//MusicBtnPlay();
SetStartPlayState(PLAY);
MusicResumePlay();
break;
case SOURCE_VIDEO_PLAYER:
if(GetCurMenuId()==MENU_VIDEO_PLAY)
{
if(STOP == GetPlayerStatus()){
SetStartPlayState(PLAY);
VideoResumePlay();
}
else
{
VideoBtnPlay();
}
}
break;
case SOURCE_IPOD:
IpodPlayCtrlPlayPause(IPODPLAY);
break;
case SOURCE_SMARTPHONE:
//为避免用户频繁的点击车机的POWER_ON_OFF按键,利用定时器过滤POWER_ON_OFF硬按键消息
if(starttimerFlag == FALSE)
{
starttimerFlag = TRUE;
set_power_off_on_send_timer(0,5*1000*100);
PhoneLinkPlayPause(TRUE);
}
else
{
flag_power_off_on_timer++;
}
break;
}
//if(SOURCE_IPOD != src)
ResetAboutTimer();
}
return 0;
}