Boost是个很强大的C++库,这个系列记录了使用Boost自定义的一系列小工具。
Timer是个很常用的工具,主要功能是每隔一段时间,触发某个事件。在很多其他的开源库中都有类似的小组件,比如QT中的qtimer。TImer中比较核心的地方在于如何触发事件,所谓触发事件,可以认为是唤起某个函数来执行。另外,在Timer运行的过程中,程序的其他线程仍然在工作。所以这会是个多线程运行的工具。
先上代码:
class MyTimer
{
public:
MyTimer(){}
~MyTimer(){
m_.try_lock();
m_.unlock();
}
void bind_signal(boost::function<void()> f){
f_ = f;
}
void start(double ms){
m_.try_lock();
m_.unlock();
boost::function<void()> func = boost::bind(&MyTimer::sleep_while, this, ms);
t_.reset(new boost::thread(func));
}
void stop(){
while (!m_.try_lock());
}
private:
void sleep_while(double t){
while (m_.try_lock()){
m_.unlock();
#if _WIN32//_MSC_VER
Sleep(t);
#else
sleep(t / 1000.0);
#endif
f_();
}
}
private:
boost::function<void()> f_;
boost::mutex m_;
boost::shared_ptr<boost::thread> t_;
};
现在来逐行分析上述代码:
void bind_signal(boost::function<void()> f){
f_ = f;
}
要触发事件,首先要告诉timer,需要执行什么样的事件(即函数),利用boost::function可以很方便的绑定需要处理的函数,甚至可以动态绑定类的成员函数。
Timer当然需要提供start和stop方法。在此,使用thread和mutex来实现,简单来说,用互斥量来控制sleep_while。
void start(double ms){
m_.try_lock();
m_.unlock();
boost::function<void()> func = boost::bind(&MyTimer::sleep_while, this, ms);
t_.reset(new boost::thread(func));
}
void stop(){
while (!m_.try_lock());
}
private:
void sleep_while(double t){
while (m_.try_lock()){
m_.unlock();
#if _WIN32//_MSC_VER
Sleep(t);
#else
sleep(t / 1000.0);
#endif
f_();
}
}