类简介
- 定时器包含两个类Timer和TimerManager,其中Timer类是内部类,不对外开放,外部直接使用TimerManager类。
- TimerManager类用小根堆管理Timer,根据超时时间排序。
- TimerManager的关键函数是addTimer、delTimer、handleExpireTimers和getNextExpireTime。
核心代码
1.添加定时器
void TimerManager::addTimer(HttpRequest* request,
const int& timeout,
const TimeoutCallBack& cb)
{
std::unique_lock<std::mutex> lock(lock_);
assert(request != nullptr);
updateTime();
Timer* timer = new Timer(now_ + MS(timeout), cb);
timerQueue_.push(timer);
if(request -> getTimer() != nullptr)
delTimer(request);
request -> setTimer(timer);
}
2.删除定时器
void TimerManager::delTimer(HttpRequest* request)
{
assert(request != nullptr);
Timer* timer = request -> getTimer();
if(timer == nullptr)
return;
timer -> del();
request -> setTimer(nullptr);
}
3.调用超时定时器的超时回调函数
void TimerManager::handleExpireTimers()
{
std::unique_lock<std::mutex> lock(lock_);
updateTime();
while(!timerQueue_.empty()) {
Timer* timer = timerQueue_.top();
assert(timer != nullptr);
if(timer -> isDeleted()) {
timerQueue_.pop();
delete timer;
continue;
}
if(std::chrono::duration_cast<MS>(timer -> getExpireTime() - now_).count() > 0) {
return;
}
timer -> runCallBack();
timerQueue_.pop();
delete timer;
}
}
4.获取最近的超时时间
int TimerManager::getNextExpireTime()
{
std::unique_lock<std::mutex> lock(lock_);
updateTime();
int res = -1;
while(!timerQueue_.empty()) {
Timer* timer = timerQueue_.top();
if(timer -> isDeleted()) {
timerQueue_.pop();
delete timer;
continue;
}
res = std::chrono::duration_cast<MS>(timer -> getExpireTime() - now_).count();
res = (res < 0) ? 0 : res;
break;
}
return res;
}
问题
1.为什么需要加锁?不加锁会有哪些安全问题?
2.为什么删除定时器函数不加锁?