Linux Posix Timer使用(转载自http://blog.csdn.net/hongszh/article/details/8608781)
2017-06-21 22:44
716 查看
初学者,大家多指教。最近用Qt在ARM9上做开发,开了多个线程,其中一个线程用到了QTimer,每隔50ms触发一次,可是程序执行一会,报出
本文转载自转载自http://blog.csdn.net/hongszh/article/details/8608781:
最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。
man timer_create/timer_settime,可以看到man帮助的详细文档:
[cpp] view
plain copy
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的函数指针类型:
[cpp] view
plain copy
typedef void (*timerTimeout)(union sigval sig);
2. 为我们的GstPlayer定义两个timer ID:
[cpp] view
plain copy
timer_t mSeekTimer;
timer_t mPrepareAsyncTimer;
3. 定义createTimer函数,创建timer,设置timeout函数
timerId: 输入输出参数
func: timer timeout函数
[cpp] view
plain copy
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的时间,单位为毫秒。
[cpp] view
plain copy
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后要做的工作
[cpp] view
plain copy
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函数:
[cpp] view
plain copy
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后要做的工作
}
调用一:
[cpp] view
plain copy
创建timer,设定prepareAsyncTimeout
开始timer,timeout时间为500ms
createTimer(&mPrepareAsyncTimer, prepareAsyncTimeout);
setTimer(&mPrepareAsyncTimer, 500/*ms*/);
调用二:
[cpp] view
plain copy
创建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
GLib:ERROR:gmain.c:1963:g_main_dispatch: assertion failed: (current->dispatching_sources == ¤t_source_link) Aborted 错误.查找问题,在QTimer的start有问题,项目紧张,也找不出其他可能引起问题的地方了。姑且暂用Posix Timer,代替QTimer.本篇文章介绍的很详细。
本文转载自转载自http://blog.csdn.net/hongszh/article/details/8608781:
最强大的定时器接口来自POSIX时钟系列,其创建、初始化以及删除一个定时器的行动被分为三个不同的函数:timer_create()(创建定时器)、timer_settime()(初始化定时器)以及timer_delete(销毁它)。
man timer_create/timer_settime,可以看到man帮助的详细文档:
[cpp] view
plain copy
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的函数指针类型:
[cpp] view
plain copy
typedef void (*timerTimeout)(union sigval sig);
2. 为我们的GstPlayer定义两个timer ID:
[cpp] view
plain copy
timer_t mSeekTimer;
timer_t mPrepareAsyncTimer;
3. 定义createTimer函数,创建timer,设置timeout函数
timerId: 输入输出参数
func: timer timeout函数
[cpp] view
plain copy
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的时间,单位为毫秒。
[cpp] view
plain copy
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后要做的工作
[cpp] view
plain copy
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函数:
[cpp] view
plain copy
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后要做的工作
}
调用一:
[cpp] view
plain copy
创建timer,设定prepareAsyncTimeout
开始timer,timeout时间为500ms
createTimer(&mPrepareAsyncTimer, prepareAsyncTimeout);
setTimer(&mPrepareAsyncTimer, 500/*ms*/);
调用二:
[cpp] view
plain copy
创建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使用
- linux下select使用--转载http://www.cnblogs.com/moonvan/archive/2012/05/26/2518881.html
- PostgreSQL安装和简单使用(转载:http://www.linuxsir.org/main/node/275)
- 【转】Linux Posix Timer使用
- 如何使用单元测试 测试WEB组件方法中的含有Session、Cookie等HttpContext功能调用的方法?[转载]
- [转载]Unix/Linux 工具: Screen 命令使用
- Linux 使用技巧集锦(转载)
- linux下使用fdisk分区 (转载小惠惠)
- Oracle安装(linux)小结(转载)来自:http://www.phpx.com/cma2896.html
- (转载)完全使用Linux
- 使用HttpContext的User属性来实现用户验证[转载]
- linux使用教程 (转载)
- Linux 内核使用的 GNU C 扩展 (转自: http://hi.baidu.com/shlongli/blog/item/22120f38c8bfe820b8998fca.html)
- [转载:越南很有魄力啊]越南政府所有电脑将使用Linux
- linux中的TIMER使用入门
- 使用反射和特性构造自己的ORM框架 转载自:http://www.cnblogs.com/xdesigner/archive/2008/06/24/1228702.html
- 在linux下使用用Valgrind查找内存泄漏和无效内存访问(转载)
- TCP/IP基础----为Linux做准备(1) 转载自:(http://www.fanqiang.com)
- linux下使用POSIX无名信号量
- (转载) 如何在Linux使用Eclipse + CDT开发C/C++程序? (OS) (Linux) (C/C++) (gcc) (g++)