在很多應(yīng)用設(shè)計(jì)中,都設(shè)計(jì)了Timer
(定時(shí)器),
用來完成特定的世間.例如在Symbian
中就有一個(gè)CPeriodic
類,它使用定時(shí)器對(duì)象來產(chǎn)生規(guī)則的定時(shí)器事件;
在流媒體的應(yīng)用Darwin
中設(shè)計(jì)了定時(shí)器;
在高效的中間件平臺(tái)ICE
中也設(shè)計(jì)了Timer;
在通信應(yīng)用中我們必定要設(shè)計(jì)Timer
來對(duì)特定的操作進(jìn)行計(jì)時(shí);
在一些應(yīng)用中通過Timer
來產(chǎn)生周期性的心跳,
來確定系統(tǒng)中的各個(gè)服務(wù)器是否工作正常 .下面我們將分別介紹Darwin
和ICE
中的定時(shí)器:Darwin
中的定時(shí)器設(shè)計(jì):
Task
class Task
{
……
Private:
EventFlags fEvents; //該Task所對(duì)應(yīng)的事件
TaskThread* fUseThisThread; // 所對(duì)應(yīng)的TaskThread.
……
};
TaskThread : Darwin中用來處理Task的線程.
TaskThreadPool: Darwin中用來管理TaskThread的類.
跟定時(shí)器有關(guān)的Task: TimeOutTask, IdleTask.
TimeOutTask 包含一個(gè)Task的指針,并且含有一個(gè)指向TimeoutTaskThread的靜態(tài)指針,并且包含一個(gè)OSQueueElem,該OSQueueElem將被加到TimeoutTaskThread的隊(duì)列中.
class TimeoutTask
{
….
private:
Task* fTask;
SInt64 fTimeoutAtThisTime;
SInt64 fTimeoutInMilSecs;
//for putting on our global queue of timeout tasks
OSQueueElem fQueueElem;
static TimeoutTaskThread* sThread;
……
};
IdleTask 公共繼承于 Task. 并且包含一個(gè)指向IdleTaskThread的靜態(tài)指針,并且包含一個(gè)OSHeapElem. IdleTask 啟動(dòng)IdleTaskThread.
class IdleTask : public Task
{
public:
……
void SetIdleTimer(SInt64 msec) { sIdleThread->SetIdleTimer(this, msec); }
void CancelTimeout() { sIdleThread->CancelTimeout(this); }
private:
OSHeapElem fIdleElem;
static IdleTaskThread* sIdleThread;
……
};
TimeoutTaskThread 公共繼承 IdleTask
class TimeoutTaskThread : public IdleTask
{
……
SInt64 TimeoutTaskThread::Run();
……
};
IdleTaskThread具有SetIdleTimer, CancelTimeout等方法.在這些方法中有IdleTask(activeObj)作為參數(shù).
class IdleTaskThread : private OSThread
{
private:
……
void SetIdleTimer(IdleTask *idleObj, SInt64 msec);
void CancelTimeout(IdleTask *idleObj);
virtual void Entry();
OSHeap fIdleHeap;
OSMutex fHeapMutex;
OSCond fHeapCond;
……
};
上面所介紹的,主要是些數(shù)據(jù)結(jié)構(gòu). 定時(shí)器設(shè)計(jì)的關(guān)鍵部分如下:
在IdleTaskThread中有一個(gè)OSHeap用來存儲(chǔ)不同的IdleTask;
OSMutex用來對(duì)對(duì)象的同步訪問進(jìn)行串行化;
OSCond用來對(duì)對(duì)象進(jìn)行Monitor.
在IdleTaskThread的SetIdleTimer方法中,調(diào)用fHeapCond.Signal()發(fā)出信號(hào),激活在該條件上等待的線程.
在IdleTaskThread的Entry方法中檢查fIdleHeap.CurrentHeapSize(),如故為0,則等代: fHeapCond.Wait(&fHeapMutex), 直到有新的IdelTimer被加入.
如果定時(shí)到了,則調(diào)用該IdleTask上的Signal(Task::kIdleEvent)方法,激活在該條件上等待的線程.然后調(diào)整等待時(shí)間, 重新進(jìn)行等待: fHeapCond.Wait(&fHeapMutex, smallTime);
ICE中的定時(shí)器設(shè)計(jì):
在ICE中有一個(gè)Time類和Timer類.
在Time中主要是定義一些對(duì)時(shí)間的轉(zhuǎn)換操作和比較操作等.
類Timer的定義如下:
class ICE_UTIL_API Timer : public virtual IceUtil::Shared, private virtual IceUtil::Thread
{
public:
……
//
// Schedule a task for execution after a given delay.
//
void schedule(const TimerTaskPtr&, const IceUtil::Time&);
//
// Schedule a task for repeated execution with the given delay
// between each execution.
//
void scheduleRepeated(const TimerTaskPtr&, const IceUtil::Time&);
//
// Cancel a task. Returns true if the task has not yet run or if
// it's a task scheduled for repeated execution. Returns false if
// the task has already run, was already cancelled or was never
// schedulded.
//
bool cancel(const TimerTaskPtr&);
private:
struct Token
{
IceUtil::Time scheduledTime;
IceUtil::Time delay;
TimerTaskPtr task;
inline Token(const IceUtil::Time&, const IceUtil::Time&, const TimerTaskPtr&);
inline bool operator<(const Token& r) const;
};
virtual void run();
IceUtil::Monitor<IceUtil::Mutex> _monitor;
bool _destroyed;
std::set<Token> _tokens;
class TimerTaskCompare : public std::binary_function<TimerTaskPtr, TimerTaskPtr, bool>
{
public:
bool operator()(const TimerTaskPtr& lhs, const TimerTaskPtr& rhs) const
{
return lhs.get() < rhs.get();
}
};
std::map<TimerTaskPtr, IceUtil::Time, TimerTaskCompare> _tasks;
IceUtil::Time _wakeUpTime;
};
該類public 繼承IceUtil::Shared, 表示它是一個(gè)共享的引用計(jì)數(shù)對(duì)象,可以使用智能指針. 該類public繼承IceUtil::Thread, 表明它為一個(gè)線程.
在Timer的destroy, schedule, scheduleRepeated 方法中調(diào)用_monitor.notify()方法,激活等待線程.
在Timer中有一個(gè)set(token) 和一個(gè)map( task).
Timer線程的運(yùn)行方式:
在定時(shí)器的運(yùn)做方式中,要用到Map, Set來記錄定時(shí)事件,并用Monitor對(duì)象來進(jìn)行定時(shí)等待.
類TimerTask public 繼承于IceUtil::Shared, 并且要求提供一個(gè)runTimerTask的方法,該方法為純虛函數(shù).
在ICE中的數(shù)據(jù)結(jié)構(gòu)不同,但用來構(gòu)造定時(shí)器的基本原理還是一致的.