先分析设计多线程定时任务管理器的思路。
首先,任务管理器类命名为WatchThread类,需要使用多线程,那我们可以使用thread类,并使用Thread里面的线程start和run。那我们可以设计如下:
#include<Thread.h> class WatchThread:private Thead { virtual void run() { cerr<<"WatchThread started"<<endl; while (is_running) { } } }现在这里面具备了执行任务了,现在差怎么样把任务弄进去?
其实任务可以看成任务管理器里面的产品,而任务管理器可以看成工厂,这样可以使用工厂的设计模式(看 wuzhekai1985 大牛里面的设计模式想到的,设计模式C++实现(1)——工厂模式)
#任务类 class WatchFunc { virtual void watch(const struct tm& now)=0; } class WatchThread:private Thead { vector<WatchFunc *> funcs; bool wtflag; void registerFunc(WatchFunc* func) { funcs.push_back(func); if (!wtflag) { wtflag = true; this->start(); } } virtual void run() { cerr<<"WatchThread started"<<endl; while (is_running) { sleep(60); struct tm now; time_t t; time(&t); localtime_r(&t, &now); for (size_t i=0; i<funcs.size(); i++) { funcs[i]->watch(now); } } } }
resgisterFunc函数是初始化各个任务,这样任务会在run里面自动运行。
在各个任务初始化时,需要使用WatchThread对象,多个任务就对应多个任务管理器WatchThead对象,并且还是多个线程,这个跟我的初衷不一样,我只想要一个任务管理器,管理多个任务。
那我们可以使用单例模式,定义一个单例模式的模板类,任务管理器WatchThread继承它。
#单例模式模板类 template <typename T> class ssingleton { protected: struct object_creator { object_creator() { ssingleton<T>::instance(); } inline void do_nothing() const { } }; static object_creator create_object; ssingleton(){}; public: typedef T object_type; static object_type & instance() { static object_type obj; create_object.do_nothing(); return obj; } static object_type& getInstance() { return instance(); } }; template <typename T> typename ssingleton<T>::object_creator ssingleton<T>::create_object;
现在就差不多了,来看看整体的例子:
template <typename T> class ssingleton//单例类 { protected: struct object_creator { object_creator() { ssingleton<T>::instance(); } inline void do_nothing() const { } }; static object_creator create_object; ssingleton(){}; public: typedef T object_type; static object_type & instance() { static object_type obj; create_object.do_nothing(); return obj; } static object_type& getInstance() { return instance(); } }; template <typename T> typename ssingleton<T>::object_creator ssingleton<T>::create_object; class WatchFunc//任务父类 { protected: struct tm last_time; public: WatchFunc() { time_t t = 0; localtime_r(&t, &last_time); } virtual ~WatchFunc() { } virtual void watch(const struct tm& now) { } void updateTime(const struct tm& now) { last_time = now; } }; class WatchThread : public ssingleton<WatchThread>, private Thread//任务管理器 { vector<WatchFunc *> funcs; bool wtflag; Lock l; public: WatchThread():wtflag(false) { } ~WatchThread() { for (size_t i=0; i<funcs.size(); i++) { delete funcs[i]; } } void registerFunc(WatchFunc* func) { l.lock(); funcs.push_back(func); if (!wtflag) { wtflag = true; this->start(); } l.unlock(); } virtual void run() { cerr<<"WatchThread started"<<endl; while (is_running) { sleep(60); struct tm now; time_t t; time(&t); localtime_r(&t, &now); for (size_t i=0; i<funcs.size(); i++) { funcs[i]->watch(now); } } } private: }; //定义多个任务类 class A: public WatchFunc { A() { WatchThread::instance().registerFunc(this);//初始化任务 } virtual void watch(const struct tm& now) { if (last_time.tm_hour != now.tm_hour) { cout << "update A" << endl; } } }; class B: public WatchFunc { B() { WatchThread::instance().registerFunc(this);//初始化任务 } virtual void watch(const struct tm& now) { if (last_time.tm_hour != now.tm_hour) { cout << "update B" << endl; } } }; class C: public WatchFunc { A() { WatchThread::instance().registerFunc(this);//初始化任务 } virtual void watch(const struct tm& now) { if (last_time.tm_hour != now.tm_hour) { cout << "update C" << endl; } } }; //定义任务,任务会定时运行(例子是每小时运行一次) A a; B b; C c;