zoukankan      html  css  js  c++  java
  • 【转】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

  • 相关阅读:
    C# Access2003操作辅助类(AccessHelper.cs)
    校园网综合管理系统(一)
    使用Devexpress开发简单进销存系统(1)数据库的建立
    软件测试(一):测试基础和缺陷管理
    异步多线程
    服务器下载文件到本地,更新服务器文件
    WCF深入浅出学习1
    利用Oracle 发送邮件(utl_smtp)
    多线程之 ThreadStart 和 ParameterizedThreadStart 委托
    javascript实现的google日历,beehive.calendar.js v0.1
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4281618.html
Copyright © 2011-2022 走看看