当前位置: 技术问答>linux和unix
Linux下的定时器的实现
来源: 互联网 发布时间:2016-06-13
本文导语: 写一个Linux下的播放器,需要一个高精度的定时器,精确到ms。 注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。 看了SDL的部分代码,他的思路是这样的 有一个timer的线...
写一个Linux下的播放器,需要一个高精度的定时器,精确到ms。
注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。
看了SDL的部分代码,他的思路是这样的
有一个timer的线程,然后这个线程里面有一个while循环来做到的
static int RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return(0);
}
SDL_ThreadedTimerCheck就是一个for循环,来历遍所有的注册过的定时器,注册信息包含一个定时器的相应函数,这样当前的间满足条件的时候就去调用对应的函数。这样实现有一个问题,当我们的SDL_timer_running移植满足的时候,这个while循环就是不停地调用SDL_ThreadedTimerCheck,而如果我们的定时器设置的比较远的一个时间,那么前面一段时间的while循环就是浪费CPU。因为我的媒体播放同时只会用到一个定时器,所以思路改进一下,这样:
delaytime time_len;
func callback;
static int RunTimer(void *unused)
{
while ( 1 ) {
Condition.wait(Mutex); //首先是挂起,等待设置定时器的条件
select//nanosleep()//线程挂起指定的时间
callback //定时器的回调
}
return(0);
}
然后在调用的时候,每次都会先改变time_len和callback,然后一个Condition.signal,通知开始定时
注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。
看了SDL的部分代码,他的思路是这样的
有一个timer的线程,然后这个线程里面有一个while循环来做到的
static int RunTimer(void *unused)
{
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(1);
}
return(0);
}
SDL_ThreadedTimerCheck就是一个for循环,来历遍所有的注册过的定时器,注册信息包含一个定时器的相应函数,这样当前的间满足条件的时候就去调用对应的函数。这样实现有一个问题,当我们的SDL_timer_running移植满足的时候,这个while循环就是不停地调用SDL_ThreadedTimerCheck,而如果我们的定时器设置的比较远的一个时间,那么前面一段时间的while循环就是浪费CPU。因为我的媒体播放同时只会用到一个定时器,所以思路改进一下,这样:
delaytime time_len;
func callback;
static int RunTimer(void *unused)
{
while ( 1 ) {
Condition.wait(Mutex); //首先是挂起,等待设置定时器的条件
select//nanosleep()//线程挂起指定的时间
callback //定时器的回调
}
return(0);
}
然后在调用的时候,每次都会先改变time_len和callback,然后一个Condition.signal,通知开始定时
|
你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。
最好能开个线程池,投递一个任务,让其他线程去执行。
|
好像没有。。
|
感觉如果就1个定时器 代码已经基本满足需求了
又不是大量的定时器管理实现 可以参考一下 ACE timer的源代码
你的SDL源码实现,感觉很拙劣。竟然用轮询。。。
又不是大量的定时器管理实现 可以参考一下 ACE timer的源代码
你的SDL源码实现,感觉很拙劣。竟然用轮询。。。
|
注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。
sleep是ms级的,所以你子线程sleep即可。
ps:ms级不是太高的要求把。
sleep是ms级的,所以你子线程sleep即可。
ps:ms级不是太高的要求把。
|
还得考虑多加一个信号用来在增加新任务的时候调整时间,
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。
|
飘过!!!!
|
定时是不是进程睡眠一段时间, 如果时间到就唤醒? 不可以让进程进入timer队列等待吗
|
进来学习