【网络组件】定时器

本节研究定时器Timer和TimerQueue的实现,并给出C++实现;

定时器

说明几点:

(1)TimerQueue应该能够高效的管理组织定时器Timer,包括未到期Timer、超时的Timer、以及能够高效的添加和删除Timer;采用stl中的multimap(内部采用红黑树来实现)来管理Timer,添加、删除、查找的时间复杂读均为O(log n),非常高效;multimap键key采用时间戳、值value采用Timer;由于key可以重复,那么真正区分Timer的是其内部的一个计数器uint64_t,采用64位;

(2)定时器采用timerfd来管理定时(timerfd_create创建、timerfd_settime修改定时时间),可将timerfd加入到epoll机制中按照IO事件相同的方式来处理定时;

(3)用户Callback回调的时序图如下:

时间戳TimeStamp声明

class TimeStamp final//ADT{public: TimeStamp() :_nanoSecondsSinceEpoch(0) { } explicit TimeStamp(uint64_t nanoSecondsSinceEpochs):_nanoSecondsSinceEpoch(nanoSecondsSinceEpochs) { } static TimeStamp now(); std::string toFormattedString(); std::string toFileNameString(); uint64_t nanoSecondsSinceEpoch() const {return _nanoSecondsSinceEpoch; } time_t secondsSinceEpoch() const {return static_cast<time_t>(_nanoSecondsSinceEpoch / cNanoSecondsPerSecond); }private: static const int cNanoSecondsPerSecond = 1000 * 1000 * 1000; uint64_t _nanoSecondsSinceEpoch;};inline time_t operator-(const TimeStamp& lhs, const TimeStamp& rhs){ return lhs.secondsSinceEpoch() – rhs.secondsSinceEpoch();}inline bool operator==(const TimeStamp& lhs, const TimeStamp& rhs){ return lhs.nanoSecondsSinceEpoch() == rhs.nanoSecondsSinceEpoch();}inline bool operator!=(const TimeStamp& lhs, const TimeStamp& rhs){ return lhs.nanoSecondsSinceEpoch() != rhs.nanoSecondsSinceEpoch();}inline bool operator<(const TimeStamp& lhs, const TimeStamp& rhs){ return lhs.nanoSecondsSinceEpoch() < rhs.nanoSecondsSinceEpoch();}}

说明几点

(1)_nanoSecondsSinceEpoch的类型为uint64_t,可表示今后的585年;

TimeStamp实现TimeStamp TimeStamp::now(){ struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); //int err = clock_gettime(CLOCK_MONOTONIC, &ts); uint64_t nanoSeconds = ts.tv_sec; return TimeStamp(ts.tv_nsec + nanoSeconds * cNanoSecondsPerSecond);}std::string TimeStamp::toFormattedString(){ time_t second = static_cast<time_t>(_nanoSecondsSinceEpoch / cNanoSecondsPerSecond); uint32_t nanoSeconds = static_cast<uint32_t>(_nanoSecondsSinceEpoch % cNanoSecondsPerSecond); struct tm result; gmtime_r(&second, &result); char buf[32]; snprintf(buf, sizeof buf, "%04d%02d%02d %02d:%02d:%02d.%09d", result.tm_year + 1900, result.tm_mon + 1,result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec, nanoSeconds); return buf;}std::string TimeStamp::toFileNameString(){ time_t second = static_cast<time_t>(_nanoSecondsSinceEpoch / cNanoSecondsPerSecond); struct tm result; gmtime_r(&second, &result); char buf[32]; snprintf(buf, sizeof buf, "[%04d%02d%02d-%02d:%02d]", result.tm_year + 1900, result.tm_mon + 1,result.tm_mday, result.tm_hour, result.tm_min); return buf;}说明几点

(1)采用clock_gettime来获得当前时间,时间可以精确到纳秒;

(2)toFormattedString()为获得时间戳的字符串表示,更加形象;

定时标识

TimerId

class TimerId final{public: explicit TimerId(int interval) :_id(timerIdProducer.getCount()),_timeStamp(Base::TimeStamp::now().nanoSecondsSinceEpoch() + interval * cNanoSecondsPerSecond) {timerIdProducer.increment(); } Base::TimeStamp timeStamp() const {return _timeStamp; } void setNewTimeStamp(int interval) {_timeStamp = Base::TimeStamp(Base::TimeStamp::now().nanoSecondsSinceEpoch() + interval * cNanoSecondsPerSecond); } uint64_t id() const {return _id; }private: uint64_t _id; Base::TimeStamp _timeStamp; static Base::AtomicCount timerIdProducer; static const uint64_t cNanoSecondsPerSecond = 1000 * 1000 * 1000; //important};inline bool operator<(const TimerId& lhs, const TimerId& rhs){ if (lhs.timeStamp() == rhs.timeStamp())return lhs.id() < rhs.id(); return lhs.timeStamp() < rhs.timeStamp();}

说明几点

(1)_timeStamp为创建Timer定时器时的时间;因为可能存在两个用户创建同一个时间刻的定时器(精确到纳秒,概率极低);故使用_id进行进一步的区分;timerIdProducer为_id计数器的发生器;

(2)operator<为TimerId的弱序比较函数;

定时器

Timer

class Timer final{public: Timer(const Timer&) = delete; Timer& operator=(const Timer&) = delete; typedef std::function<void()> TimerCallback; Timer(const TimerCallback& cb, uint32_t intervals, bool cycles):_timerCallback(cb),_interval(intervals),_cycle(cycles),_timerId(_interval) { } TimerId timerId() const {return _timerId; } Base::TimeStamp timeStamp() const {return _timerId.timeStamp(); } void setNewTimeStamp() {_timerId.setNewTimeStamp(_interval); } uint64_t id() const {return _timerId.id(); } bool cycle() const {return _cycle; } uint32_t interval() const {return _interval; } TimerCallback timerCallback() {return _timerCallback; }private: TimerCallback _timerCallback; uint32_t _interval; bool _cycle; TimerId _timerId;};

说明几点

纵然伤心,也不要愁眉不展,因为你不知是谁会爱上你的笑容

【网络组件】定时器

相关文章:

你感兴趣的文章:

标签云: