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

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

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

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

我的实现如下:

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

  1. typedef void (*timerTimeout)(union sigval sig);

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

  1. timer_t  mSeekTimer;
  2. timer_t  mPrepareAsyncTimer;

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

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

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

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

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

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

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

  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函数:

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

调用一:

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

调用二:

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

参考:

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

【转】Linux Posix Timer使用的更多相关文章

  1. Linux时间子系统之(六):POSIX timer

    专题文档汇总目录 Notes:首先讲解了POSIX timer的标识(唯一识别).POSIX Timer的组织(管理POSIX Timer).内核中如何抽象POSIX Timer:然后分析了POSIX ...

  2. Linux时间子系统(六) POSIX timer

    一.前言 在用户空间接口函数文档中,我们描述了和POSIX timer相关的操作,主要包括创建一个timer.设定timer.获取timer的状态.获取timer overrun的信息.删除timer ...

  3. Linux posix线程库总结

    由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...

  4. POSIX Timer

    SYNOPSIS #include <signal.h> /* only timer_create need this header */ #include <time.h> ...

  5. linux POSIX 信号量介绍

    信号量一.什么是信号量信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)使用.多线程可以同时运行多个线程函数完成功能,但是对于共享数据如果不加以锁定,随意改变共享数据的值会发生 ...

  6. linux Posix 信号量 一

    信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语. linux提供两种信号量,“内核信号量”和“用户态进程信号量”,“用户态信号量”又分为“Posix”,“System V”信号 ...

  7. linux Posix线程同步(条件变量) 实例

    条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行 应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信 ...

  8. linux Posix 信号量 二

    一.Posix信号量 1.Posix信号量分为两种: 1.   有名信号量:使用Posix IPC名字标识(有名信号量总是既可用于线程间的同步,又可以用于进程间的同步) 2.   内存信号量:存放在共 ...

  9. linux POSIX信号量

    POSIX信号量机制是3种IPC机制之一,3种IPC机制源于POSIX.1的实时扩展. 创建一个新的命名信号量或者使用一个现有信号量 #include <fcntl.h> #include ...

随机推荐

  1. PE文件结构详解(六)重定位

    前面两篇 PE文件结构详解(四)PE导入表 和 PE文件结构详解(五)延迟导入表 介绍了PE文件中比较常用的两种导入方式,不知道大家有没有注意到,在调用导入函数时系统生成的代码是像下面这样的: 在这里 ...

  2. Node.js 4.0.0:灵雀云和 OneAPM 的整合测试

    关于 Node.js 4.0.0 稳定版刚刚推出,备受期待,迫不及待地想用它写点东西:此外,要把 Demo 放到 Internet 上得有一个公网 IP ,看到灵雀云挺不错的而且提供域名解析,简直业界 ...

  3. POJ2104 k-th number 划分树

    又是不带修改的区间第k大,这次用的是一个不同的方法,划分树,划分树感觉上是模拟了快速排序的过程,依照pivot不断地往下划分,然后每一层多存一个toleft[i]数组,就可以知道在这一层里从0到i里有 ...

  4. hdu 1172 猜数字(暴力枚举)

    题目 这是一道可以暴力枚举的水题. //以下两个都可以ac,其实差不多一样,呵呵 //1: //4 wei shu #include<stdio.h> struct tt { ],b[], ...

  5. java基础知识回顾之java Socket学习(一)--UDP协议编程

    UDP传输:面向无连接的协议,不可靠,只是把应用程序传给IP层的数据报包发送出去,不保证发送出去的数据报包能到达目的地.不用再客户端和服务器端建立连接,没有超时重发等机制,传输速度快是它的优点.就像寄 ...

  6. 转:samba 启动和重新启动 以及在虚拟系统和实际系统怎么实现软件交换

    转自:http://blog.csdn.net/zwhfyy/article/details/1605151 启动 smb start 重新启动 root 用户登陆 CHQ_WEB:/etc/init ...

  7. Unity打包APK横屏时的注意事项

    由于你在Unity设置了横屏. 所以也需要在安卓的AndroidManifest.xml文件中, application/activity下声明为横屏.否则会黑屏,根本不给你报错,愁死你. 加上这一句 ...

  8. Arraysort

    import java.util.*;public class Arraysort{ public static void main(String[]args){ int[]a={100,34,88, ...

  9. swift:类型转换(is用作判断检测、as用作类型向下转换)

    类型转换是一种检查类实例的方式,并且哦或者也是让实例作为它的父类或者子类的一种方式.   类型转换在Swift中使用is 和 as操作符实现.这两个操作符提供了一种简单达意的方式去检查值的类型或者转换 ...

  10. Linux进程的睡眠和唤醒简析

    COPY FROM:http://www.2cto.com/os/201204/127771.html 1 Linux进程的睡眠和唤醒 在Linux中,仅等待CPU时间的进程称为就绪进程,它们被放置在 ...