Linux下的定时器的实现

时间:2023-01-22 23:36:39
写一个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,通知开始定时

14 个解决方案

#1


你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。

#2


linux自带  有没有这样精度的定时器的实现

#3


好像没有。。

#4


感觉如果就1个定时器  代码已经基本满足需求了

又不是大量的定时器管理实现 可以参考一下 ACE timer的源代码

你的SDL源码实现,感觉很拙劣。竟然用轮询。。。

#5


引用 1 楼 pottichu 的回复:
你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。


我其他线程实现了一个消息队列,callback就是往队列里压一跳消息

#6


引用 5 楼 jinlking 的回复:
引用 1 楼 pottichu 的回复:
你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。


我其他线程实现了一个消息队列,callback就是往队列里压一跳消息


恩。 这样也不错。

#7


还得考虑多加一个信号用来在增加新任务的时候调整时间,
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。

#8


飘过!!!!

#9


定时是不是进程睡眠一段时间, 如果时间到就唤醒? 不可以让进程进入timer队列等待吗

#10


进来学习

#11


引用 7 楼 playmud 的回复:
还得考虑多加一个信号用来在增加新任务的时候调整时间,
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。


不懂

#12


注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。 

sleep是ms级的,所以你子线程sleep即可。
ps:ms级不是太高的要求把。

#13


ms可能不大,是为了以后的扩展的方便,所以要求那么高的精确度。
结贴,谢谢各位大侠

#14


该回复于2011-05-12 09:06:57被版主删除

#1


你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。

#2


linux自带  有没有这样精度的定时器的实现

#3


好像没有。。

#4


感觉如果就1个定时器  代码已经基本满足需求了

又不是大量的定时器管理实现 可以参考一下 ACE timer的源代码

你的SDL源码实现,感觉很拙劣。竟然用轮询。。。

#5


引用 1 楼 pottichu 的回复:
你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。


我其他线程实现了一个消息队列,callback就是往队列里压一跳消息

#6


引用 5 楼 jinlking 的回复:
引用 1 楼 pottichu 的回复:
你的设计基本可以满足要求,但,既然要保证定时器的精度,那么, callback 就不能在 定时器线程里执行,
最好能开个线程池,投递一个任务,让其他线程去执行。


我其他线程实现了一个消息队列,callback就是往队列里压一跳消息


恩。 这样也不错。

#7


还得考虑多加一个信号用来在增加新任务的时候调整时间,
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。

#8


飘过!!!!

#9


定时是不是进程睡眠一段时间, 如果时间到就唤醒? 不可以让进程进入timer队列等待吗

#10


进来学习

#11


引用 7 楼 playmud 的回复:
还得考虑多加一个信号用来在增加新任务的时候调整时间,
否则当你当前定时最大的是2小时,结果来了2个任务是需要5分钟的,结果等了2小时才触发。


不懂

#12


注意我这里实现的是定时器,而不是简单的延时,所以我是不是应该单独的创建一个线程来实现。 

sleep是ms级的,所以你子线程sleep即可。
ps:ms级不是太高的要求把。

#13


ms可能不大,是为了以后的扩展的方便,所以要求那么高的精确度。
结贴,谢谢各位大侠

#14


该回复于2011-05-12 09:06:57被版主删除