Linux Posix Timer使用


最强大的定时器接口来自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);

2. 为我们的GstPlayer定义两个timer ID:
    timer_t  mSeekTimer;
    timer_t  mPrepareAsyncTimer;
 
3. 定义createTimer函数,创建timer,设置timeout函数
    timerId: 输入输出参数
    func:    timer timeout函数

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开始定时器计时。


-这里,将interval参数设置为0,指定我的定时器不工作在循环模式。
-timeMSec是输入参数,指定time out的时间,单位为毫秒。
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后要做的工作
}

prepareAsyncTimeout的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/
http://blog.csdn.net/leo9150285/article/details/8271910


你可能感兴趣的:(Linux Posix Timer使用)