很久之前听著名页游服务器主程讲座时,讲到过定时器的实现,基本思路如下(易语言)
while(true)
{
对定时器进行排序。
for(遍历定时器)
{
if 如果定时器到:
callback;
else
break;
}
usleep(20);
}
按照这个思路,我们继续我们的设计:
1: 首先 定义一个Thread类:
/*
* Thread.h
*
* Created on: Sep 11, 2012
* Author: root
*/
#ifndef THREAD_H_
#define THREAD_H_
#include <pthread.h>
class Thread {
public:
enum THREADSTATE
{
IDLE,
WORK,
BUSY,
};
public:
Thread();
virtual ~Thread();
virtual void* run(void) = 0;
virtual int start(void);
virtual int cancel(void);
pthread_t get_pid() const
{
return pid;
}
protected:
THREADSTATE _thread_state;
private:
pthread_t pid;
static void* thread_entry(void* para);
};
#endif /* THREAD_H_ */
实现代码Thread.cpp:
View
Code
/*
* Thread.cpp
*
* Created on: Sep 11, 2012
* Author: root
*/
#include "Thread.h"
Thread::Thread() {
// TODO Auto-generated constructor stub
}
Thread::~Thread() {
// TODO Auto-generated destructor stub
}
void* Thread::thread_entry(void* para)
{
Thread *pThread = static_cast<Thread *>(para);
return pThread->run();
}
int Thread::start(void)
{
if(pthread_create(&pid,0,thread_entry,static_cast<void *>(this)) < 0)
{
pthread_detach(this->pid);
return -1;
}
return 0;
}
int Thread::cancel(void)
{
pthread_cancel(this->pid);
return 0;
}
2:定义定时器,和定时器线程:
TimerThread.h
/*
* Timer.h
*
* Created on: Sep 11, 2012
* Author: root
*/
#ifndef TIMER_H_
#define TIMER_H_
#include "Thread.h"
#include <list>
using namespace std;
struct Timer
{
void *_args;
int (*_callback)();
int _interval;
int leftsecs;
void open(int interval,int (*callback)())
{
_interval = interval * 1000;
leftsecs = _interval;
_callback = callback;
}
bool operator < (Timer _timer)
{
return _timer.leftsecs < this->leftsecs;
}
bool operator == (Timer _timer)
{
return _timer.leftsecs == this->leftsecs;
}
};
class TimerThread : public Thread
{
public:
static TimerThread* _instance;
static TimerThread* get_instance();
virtual void* run(void);
virtual ~TimerThread();
void Register(Timer _timer);
void unRegister(Timer _timer);
private:
TimerThread();
list<Timer> _timer_list;
};
extern unsigned int get_systime_clock();
#define TIMERMANAGE TimerThread::get_instance()
#endif /* TIMER_H_ */
实现代码:TimerThread.cpp
View
Code
/*
* Timer.cpp
*
* Created on: Sep 11, 2012
* Author: root
*/
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include "Timer.h"
TimerThread* TimerThread::_instance;
TimerThread::TimerThread()
{
}
TimerThread::~TimerThread()
{
}
void* TimerThread::run(void)
{
while(true)
{
unsigned int start_clock = get_systime_clock();
this->_timer_list.sort();
list<Timer>::iterator iter;
for(iter = this->_timer_list.begin();
iter != this->_timer_list.end();
iter ++)
{
iter->leftsecs --;
if(iter->leftsecs == 0)
{
iter->_callback();
iter->leftsecs = iter->_interval;
}
}
unsigned int end_clock = get_systime_clock();
usleep(1000 + start_clock - end_clock);
}
return (void*)0;
}
void TimerThread::Register(Timer _timer)
{
this->_timer_list.push_back(_timer);
}
void TimerThread::unRegister(Timer _timer)
{
this->_timer_list.remove(_timer);
}
TimerThread* TimerThread::get_instance()
{
if(_instance == NULL)
{
_instance = new TimerThread();
}
return _instance;
}
unsigned int get_systime_clock()
{
struct timeval now;
gettimeofday(&now,NULL);
return now.tv_sec*1000 + now.tv_usec/1000;
}
3: 测试函数:
View
Code
//============================================================================
// Name : test.cpp
// Author : archy
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <string>
#include <stdio.h>
#include <sys/types.h>
#include "Timer.h"
using namespace std;
int handle_timeout()
{
unsigned int time = get_systime_clock();
printf("time out,%u\n",time);
return 0;
}
int main()
{
Timer _timer;
_timer.open(1,handle_timeout);
TIMERMANAGE->Register(_timer);
TIMERMANAGE->start();
getchar();
return 0;
}
目前存在的问题:定时不准,主要是由于usleep()之后 ,不能及时醒,这个是因为Linux线程调度引起的。
改进的方向:1. TimerThread 里面的list换成优先队列
2. 添加时间纠正,在测试中发现,每次大概慢100us左右,这对于长时间的定时器是致命。
也想听听广大网友的意见,感激不尽。