最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。
man timer_create/timer_settime,可以看到man帮助的详细文档:
TIMER_CREATE(2) Linux Programmer's Manual NAME timer_create - create a POSIX per-process timer SYNOPSIS #include <signal.h> #include <time.h> int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid); int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec * old_value); int timer_gettime(timer_t timerid, struct itimerspec *curr_value);
我的实现如下:
1. 定义timer timeout的函数指针类型:
typedef void (*timerTimeout)(union sigval sig);
timer_t mSeekTimer; timer_t mPrepareAsyncTimer;
void createTimer(timer_t *timerId, timerTimeout func) { struct sigevent sev; sev.sigev_notify = SIGEV_THREAD; sev.sigev_signo = SIGRTMIN; sev.sigev_value.sival_ptr = gPlayer; sev.sigev_notify_function = func; sev.sigev_notify_attributes = NULL; /* create timer */ if (timer_create (CLOCK_REALTIME, &sev, timerId) == -1) { ERR ("timer_create, error"); return; } if (*timerId == -1) ERR ("timer_create error, id is -1"); return; }
4. setTimer函数, 调用linux的timer_settime, 如果还没到time out,重置之前的timer
如果已经time out,那就得重新调用createTimer生成有效的timer ID,然后才能调用setTimer开始定时器计时。
void setTimer(timer_t *timerId, int timeMSec) { struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = timeMSec / 1000; its.it_value.tv_nsec = (timeMSec % 1000) * 1000000; its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 0; if (timer_settime (*timerId, 0, &its, NULL) == -1) { ERR ("timer_settime error"); } DEBUG ("call timer_settime reset timer done."); return; }
seekTimerTimeout函数,time out以后,销毁之前调用createTimer创建的timer,完成time out后要做的工作
void seekTimerTimeout(union sigval sig) { GstPlayer *player = (GstPlayerplayer*)sig.sival_ptr; if (player->mSeekTimer != -1) { DEBUG("timeout, delete timer:Id = %d", player->mSeekTimer); timer_delete(player->mSeekTimer); player->mSeekTimer = -1; } // ... 完成time out后要做的工作 }
void prepareAsyncTimeout(union sigval sig) { GstStateChangeReturn state_return; GstPlayer *player = (GstPlayerplayer*)sig.sival_ptr; if (player->mPrepareAsyncTimer != -1) { DEBUG("timeout, delete timer:Id = %d", player->mPrepareAsyncTimer); timer_delete(player->mPrepareAsyncTimer); player->mPrepareAsyncTimer = -1; } // ...完成time out后要做的工作 }
创建timer,设定prepareAsyncTimeout 开始timer,timeout时间为500ms createTimer(&mPrepareAsyncTimer, prepareAsyncTimeout); setTimer(&mPrepareAsyncTimer, 500/*ms*/);
创建timer,设定timeout回调函数。 // create timer if (mSeekTimer == -1) { createTimer(&mSeekTimer, seekTimerTimeout); } 判断mSeekTimer是否有效,有效,计算到timeout的剩余时间,如果还没到timeout,重置timer, 开始新的计时。 // if timer exist and not expire, reset timer. if (mSeekTimer != -1) { gulong remaining = 0; //us struct itimerspec its; timer_gettime(mSeekTimer, &its); remaining = its.it_value.tv_sec * 1000000 its.it_value.tv_nsec / 1000; DEBUG ("-- remaining time = %lu us", remaining); if ((100/*ms*/ * 1000 - remaining) > 0) { setTimer(&mSeekTimer, 100/*ms*/); DEBUG ("the new seek interval < 100ms, return"); mSeekCount = 1; return TRUE; } }
参考:
http://blog.163.com/zheng_he_xiang/blog/static/18650532620116311020390/