【转】Linux Posix Timer使用

原文网址:http://blog.csdn.net/hongszh/article/details/8608781

最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。

man timer_create/timer_settime,可以看到man帮助的详细文档:

[cpp] view plaincopy
 
  1. TIMER_CREATE(2)                                      Linux Programmer's Manual    
  2.   
  3. NAME  
  4.        timer_create - create a POSIX per-process timer  
  5.   
  6. SYNOPSIS  
  7.        #include <signal.h>  
  8.        #include <time.h>  
  9.   
  10.        int timer_create(clockid_t clockid, struct sigevent *sevp,  
  11.                         timer_t *timerid);  
  12.        int timer_settime(timer_t timerid, int flags,  
  13.                          const struct itimerspec *new_value,  
  14.                          struct itimerspec * old_value);  
  15.        int timer_gettime(timer_t timerid, struct itimerspec *curr_value);  

我的实现如下:

1. 定义timer timeout的函数指针类型: 

[cpp] view plaincopy
 
  1. typedef void (*timerTimeout)(union sigval sig);  


2. 为我们的GstPlayer定义两个timer ID:

[cpp] view plaincopy
 
  1. timer_t  mSeekTimer;  
  2. timer_t  mPrepareAsyncTimer;  

 
3. 定义createTimer函数,创建timer,设置timeout函数
    timerId: 输入输出参数
    func:    timer timeout函数

[cpp] view plaincopy
 
  1. void createTimer(timer_t *timerId, timerTimeout func)  
  2. {  
  3.     struct sigevent sev;  
  4.   
  5.     sev.sigev_notify = SIGEV_THREAD;  
  6.     sev.sigev_signo = SIGRTMIN;  
  7.     sev.sigev_value.sival_ptr = gPlayer;  
  8.     sev.sigev_notify_function = func;  
  9.     sev.sigev_notify_attributes = NULL;  
  10.   
  11.     /* create timer */  
  12.     if (timer_create (CLOCK_REALTIME, &sev, timerId) == -1)  
  13.     {  
  14.         ERR ("timer_create, error");  
  15.         return;  
  16.     }  
  17.   
  18.     if (*timerId == -1)  
  19.         ERR  ("timer_create error, id is -1");  
  20.     return;  
  21. }  

4. setTimer函数, 调用linux的timer_settime, 如果还没到time out,重置之前的timer

如果已经time out,那就得重新调用createTimer生成有效的timer ID,然后才能调用setTimer开始定时器计时。


-这里,将interval参数设置为0,指定我的定时器不工作在循环模式。
-timeMSec是输入参数,指定time out的时间,单位为毫秒。

[cpp] view plaincopy
 
  1. void setTimer(timer_t *timerId, int timeMSec)  
  2. {  
  3.     struct itimerspec its;  
  4.   
  5.     /* Start the timer */  
  6.     its.it_value.tv_sec = timeMSec / 1000;  
  7.     its.it_value.tv_nsec = (timeMSec % 1000) * 1000000;  
  8.   
  9.     its.it_interval.tv_sec = 0;  
  10.     its.it_interval.tv_nsec = 0;  
  11.   
  12.     if (timer_settime (*timerId, 0, &its, NULL) == -1)  
  13.     {  
  14.         ERR ("timer_settime error");  
  15.     }  
  16.     DEBUG ("call timer_settime reset timer done.");  
  17.     return;  
  18. }  

seekTimerTimeout函数,time out以后,销毁之前调用createTimer创建的timer,完成time out后要做的工作

[cpp] view plaincopy
 
  1. void seekTimerTimeout(union sigval sig)  
  2. {  
  3.     GstPlayer *player = (GstPlayerplayer*)sig.sival_ptr;  
  4.     if (player->mSeekTimer != -1)  
  5.     {  
  6.         DEBUG("timeout, delete timer:Id = %d",  
  7.                 player->mSeekTimer);  
  8.         timer_delete(player->mSeekTimer);  
  9.         player->mSeekTimer = -1;  
  10.     }  
  11.     // ... 完成time out后要做的工作  
  12. }  


prepareAsyncTimeout的time out函数:

[cpp] view plaincopy
 
  1. void prepareAsyncTimeout(union sigval sig)  
  2. {  
  3.     GstStateChangeReturn state_return;  
  4.     GstPlayer *player = (GstPlayerplayer*)sig.sival_ptr;  
  5.   
  6.     if (player->mPrepareAsyncTimer != -1)  
  7.     {  
  8.         DEBUG("timeout, delete timer:Id = %d",  
  9.                 player->mPrepareAsyncTimer);  
  10.         timer_delete(player->mPrepareAsyncTimer);  
  11.         player->mPrepareAsyncTimer = -1;  
  12.     }  
  13.   
  14.     // ...完成time out后要做的工作  
  15. }  


调用一:

[cpp] view plaincopy
 
  1. 创建timer,设定prepareAsyncTimeout  
  2. 开始timer,timeout时间为500ms  
  3.   
  4.         createTimer(&mPrepareAsyncTimer, prepareAsyncTimeout);  
  5.         setTimer(&mPrepareAsyncTimer, 500/*ms*/);  


调用二: 

[cpp] view plaincopy
 
  1. 创建timer,设定timeout回调函数。  
  2.     // create timer  
  3.     if (mSeekTimer == -1)  
  4.     {  
  5.         createTimer(&mSeekTimer, seekTimerTimeout);  
  6.     }  
  7.   
  8. 判断mSeekTimer是否有效,有效,计算到timeout的剩余时间,如果还没到timeout,重置timer,  
  9. 开始新的计时。  
  10.     // if timer exist and not expire, reset timer.  
  11.     if (mSeekTimer != -1)  
  12.     {  
  13.         gulong remaining = 0; //us  
  14.         struct itimerspec its;  
  15.   
  16.         timer_gettime(mSeekTimer, &its);  
  17.         remaining = its.it_value.tv_sec * 1000000  
  18.                    its.it_value.tv_nsec / 1000;  
  19.         DEBUG ("-- remaining time = %lu us", remaining);  
  20.         if ((100/*ms*/ * 1000 - remaining) > 0)  
  21.         {  
  22.            setTimer(&mSeekTimer, 100/*ms*/);  
  23.            DEBUG ("the new seek interval < 100ms, return");  
  24.            mSeekCount = 1;  
  25.            return TRUE;  
  26.         }  
  27.     }  

参考:

http://blog.163.com/zheng_he_xiang/blog/static/18650532620116311020390/
http://blog.csdn.net/leo9150285/article/details/8271910

原文地址:https://www.cnblogs.com/wi100sh/p/4281618.html