定时器Timer的实现
定时器在实际项目中会用的比较平凡。因此,本文首先介绍定时器Timer的windows版本,跨平台的定时器将在下一篇文章中介绍。它们的源代码均用C++编写。源代码详见:https://github.com/duankai/Timer。
1. 定时器结构体类型
typedef struct TIMER_T
{int uiTimerID;long lMilliSecond;void (* lpProcessFunction)(void * pvData);void * pvData;
} TIMER_T;
2. 定时器类
class Timer
{
public:Timer();int SetTimer(long lMilliSecond, //the millisecond of timervoid (*_lpProcessFunction)(void * pvData),void * pvData);bool CancleTimer(int ulTimerID);bool GetInstanceStatus();~Timer();
private:static DWORD WINAPI ScanTimerQueue(LPVOID lp);static int CmpFunc(TIMER_T * t1, TIMER_T * t2);
private:static SortBinaryTree<TIMER_T> * m_pstSBT;static int m_uiTimerID;bool m_bInit;HANDLE m_hScan;std::map<int, TIMER_T *> m_map;
};
3. 定时器的设置
int Timer::SetTimer(long lMilliSecond, //the millisecond of timervoid (*_lpProcessFunction)(void * pvData),void * pvData
)
{TIMER_T * stTimerInstc = (TIMER_T *)malloc(sizeof(TIMER_T));if (!stTimerInstc){return INVILID_TIMER_ID;}stTimerInstc->lpProcessFunction = _lpProcessFunction;/*The GetTickCount() function will be zero when your system run more than 49.7 days.*/stTimerInstc->lMilliSecond = GetTickCount() + lMilliSecond;stTimerInstc->uiTimerID = ++m_uiTimerID;stTimerInstc->pvData = pvData;if (m_pstSBT->InsertTreeNode(stTimerInstc)){m_map.insert(std::pair<int,TIMER_T *>(m_uiTimerID, stTimerInstc));return m_uiTimerID;} else{free(stTimerInstc);stTimerInstc = NULL;return INVILID_TIMER_ID; }
}
4. 取消定时器
bool Timer::CancleTimer(int ulTimerID)
{std::map<int, TIMER_T *>::iterator itor_map;itor_map = m_map.find(ulTimerID);if (itor_map == m_map.end()){return false;}if (m_pstSBT->DeleteTreeNode((void *)itor_map->second)){free(itor_map->second);itor_map->second = NULL;m_map.erase(itor_map);return true;}else{return false; }
}
5. 定时器扫描队列
DWORD WINAPI Timer::ScanTimerQueue(LPVOID lp)
{LONG ulCurrTime;while(1)
{ulCurrTime = GetTickCount();if (NULL != m_pstSBT->GetSmallestNode() &&m_pstSBT->GetSmallestNode()->lMilliSecond <= ulCurrTime){TIMER_T * pstTimer = m_pstSBT->DeleteSmallestNode();if (NULL != pstTimer){pstTimer->lpProcessFunction(pstTimer->pvData);free(pstTimer);pstTimer = NULL;}}SLEEP(100);}return 0;
}
总结:Timer实现了定时器的主要功能,设置定时器和取消定时器,同时,在设置定时器时通过提供一个回调函数来完成相关工作。定时器存储在SortBinaryTree中,便于扫描。
存在的问题:由于在设置定时器的时候采用了GetTickCount()函数,因此限制了服务器的连续运行时间不得超过49.7天,在大型服务代码的编写中,这将通过其他替代函数完成这一类似功能。