Visual C++ 7.1Visual C++ 8.0Visual C++ 7.0C++/CLIWin32Windows 2000设计/图形Visual C++ 6.0Windows XPC中级WindowsC++
自制的轻量级调度程序






2.44/5 (9投票s)
基于定时器的任务调度程序
引言
在某些时候,需要以预定的时间间隔执行任务。这里提供的解决方案是一组 C++ 类,它为 TimerQueue API 提供了一个包装。
使用代码
该调度器由 CTask 类和 CScheduler 类组成... 调度器维护一个任务列表,当与任务关联的计时器到期时,调度器将执行这些任务。当调度器执行任务时,缓存在 CTask 类中的用户定义的的回调函数将被执行。该调度器提供接口来排队新的任务和取消用户排队的任务。
以下是 CTask 类的类声明。
//Unit of execution scheduled by CScheduler
class CTask{
friend VOID CALLBACK CTimerScheduler::WaitOrTimerCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired);
private:
HANDLE hQueueTimer_; //handle to timerqueue for this task
void(*callback_)(void);//user defined callback function
CScheduler& sched_;//the scheduler
public:
CTask(CScheduler& sched, void(*callback)(void)) :
hQueueTimer_(0), sched_(sched), callback_(callback){}
void setHandle(HANDLE hQueueTimer);
void finish();
};
以下是 CScheduler 类的类声明
/*Prototypes of functions to be pulled from kernel32.dll*/
typedef VOID (CALLBACK *WAITORTIMERCALLBACK)(PVOID lpParameter,BOOLEAN TimerOrWaitFired);
typedef HANDLE (*CREATETIMERQUEUE)(void);
typedef BOOL (CALLBACK *CREATETIMERQUEUETIMER)(
PHANDLE phNewTimer,
HANDLE TimerQueue,
WAITORTIMERCALLBACK callback,
PVOID Parameter,
DWORD DueTime,
DWORD Period,
ULONG Flags
);
typedef BOOL (CALLBACK *DELETETIMERQUEUETIMER)(
HANDLE TimerQueue,
HANDLE Timer,
HANDLE CompletionEvent
);
typedef BOOL (CALLBACK *DELETETIMERQUEUE)(
HANDLE TimerQueue
);
/**/
class CScheduler{
friend CTask;
friend VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired);
private:
unsigned long interval_;
list<CTask*> tasks_;
HANDLE hTimer_;
HMODULE hLibrary_;
static CRITICAL_SECTION cs_;
private:
static VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired);
CREATETIMERQUEUE createTimer;
DELETETIMERQUEUE deleteTimerQueue;
CREATETIMERQUEUETIMER createTimerQueueTimer;
DELETETIMERQUEUETIMER deleteTimerQueueTimer;
public:
~CScheduler();
void start();
void stop();
void enqueueTask(int interval, void (*callback)(void));
void removeTask(CTask* task);
void cancelTasks();
};
要在您的代码中使用这些类,请将代码复制到各自的文件中,并在您的项目中包含它们。
#include <windows.h>
#include "stdafx.h"
#include "Scheduler.h"
void UserSuppliedFunction(){
static int x = 0;
printf("function called %ld\n", ++x);
}
int main(int argc, char* argv[])
{
CScheduler sched;
sched.start();
unsigned int i = 0xFFFFFFFF;
while( i-- ){
sched.enqueueTask((i/10000000)*2, UserSuppliedFunction);
Sleep(5);
if( (i%100) == 0 ){
printf("cancelling....\n");
sched.cancelTasks();
}
}
sched.cancelTasks();
sched.stop();
Sleep(1000);
return 0;
}
以下是类的实现
#include "Scheduler.h"
#include
CRITICAL_SECTION CScheduler::cs_ ;
void
CScheduler::start(){
hLibrary_ = LoadLibrary("kernel32");
createTimer =
(CREATETIMERQUEUE)GetProcAddress(hLibrary_, "CreateTimerQueue");
deleteTimerQueue =
(DELETETIMERQUEUE)GetProcAddress(hLibrary_, "DeleteTimerQueue");
createTimerQueueTimer =
(CREATETIMERQUEUETIMER)GetProcAddress(hLibrary_, "CreateTimerQueueTimer");
deleteTimerQueueTimer =
(DELETETIMERQUEUETIMER)GetProcAddress(hLibrary_, "DeleteTimerQueueTimer");
InitializeCriticalSection(&cs_);
hTimer_ = createTimer();
}
void
CScheduler::stop(){
cancelTasks();
deleteTimerQueue(hTimer_);
DeleteCriticalSection(&cs_);
FreeLibrary(hLibrary_);
}
void
CScheduler::enqueueTask( int interval, void(*callback)(void) ){
CTask* newTask = new CTask(*this, callback);
HANDLE hQueueTimer = 0;
EnterCriticalSection(&cs_);
createTimerQueueTimer( &hQueueTimer, hTimer_, (WAITORTIMERCALLBACK)WaitOrTimerCallback, (void*)newTask, interval, 0, WT_EXECUTEINPERSISTENTTHREAD | WT_EXECUTEONLYONCE );
newTask->setHandle(hQueueTimer);
tasks_.push_back(newTask);
LeaveCriticalSection(&cs_);
}
void
CScheduler::cancelTasks(){
EnterCriticalSection(&cs_);
while(1){
list::iterator iter = tasks_.begin();
if(iter == tasks_.end()) break;
iter.operator *()->finish();
}
LeaveCriticalSection(&cs_);
}
void
CScheduler::removeTask(CTask* task){
tasks_.remove(task);
delete task;
}
VOID CALLBACK
CScheduler::WaitOrTimerCallback(PVOID lpParameter,BOOLEAN TimerOrWaitFired){
EnterCriticalSection(&CScheduler::cs_);
CTask* task = static_cast(lpParameter);
task->callback_();
task->finish();
LeaveCriticalSection(&CScheduler::cs_);
}
void
CTask::setHandle(HANDLE hQueueTimer){
hQueueTimer_ = hQueueTimer;
}
void
CTask::finish(){
sched_.deleteTimerQueueTimer(sched_.hTimer_, hQueueTimer_, NULL);
sched_.removeTask(this);
}
这是软件的第一个版本,后续版本中可以期待以下更新... 目前,任务只能执行一次,可以使其周期性执行... 用户定义的函数参数可以缓存在 CTask 类中,并作为参数传递给回调函数。