首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定时器实现

问定时器实现
EN

Code Review用户
提问于 2012-05-15 20:42:06
回答 1查看 1.7K关注 0票数 1

我有一个Visual 2008 C++03项目,需要一个计时器。我有一个运行良好的实现,但我希望社区就如何改进它提出任何一般性建议。(更通用、创建计时器的成本较低等)

代码语言:javascript
复制
class Timer
{
public:
    typedef boost::function< void( ) > OnTimer;

    Timer( const OnTimer& f, DWORD timeout )
        : cancel_event_( ::CreateEvent( NULL, FALSE, FALSE, NULL ), ::CloseHandle ),
          timer_thread_( boost::bind( &Timer::TimerThread, cancel_event_.get(), f, timeout ) ),
          timeout_( timeout )
    {
    };

    ~Timer() { ::SetEvent( cancel_event_.get() ); };

    DWORD Timeout() const { return timeout_; };

private:

    static void TimerThread( HANDLE cancel_event, const OnTimer& f, DWORD timeout )
    {
        if( WAIT_OBJECT_0 != ::WaitForSingleObject( cancel_event, timeout ) )
            f();
    };

    /// time to wait for the timer to fire
    UINT timeout_;
    /// event signaled when the timer should be canceled
    boost::shared_ptr< void > cancel_event_;
    /// thread that runs the timer (similar to boost::thread, but doesn't require `localtime`, `gmtime`, or `abort`)
    util::CThread timer_thread_;
}; // class Timer

先发制人:

  • 我的项目没有窗口消息泵,所以SetTimer是不合适的。
  • 我不想花费导入mmtimer库的费用。
  • 我只能使用boost头库,因此boost::timer是不合适的。
  • 我倾向于将讨论局限于这段代码。
EN

回答 1

Code Review用户

回答已采纳

发布于 2012-05-15 23:42:57

我认为您可以创建一个线程来处理所有定时器。创建新计时器时,应将其添加到"timers to触发器“的(同步)队列中。后台线程必须等待最近的计时器被触发。此外,每次修改定时器队列并重新计算“哪个是现在最接近的定时器?”时,您都应该唤醒它。

当队列为空时,后台线程可以被销毁(连接),也可以等待“退出”事件(或创建另一个计时器)。这些只是细节。后台线程可以由第一个定时器创建,并在最后一个定时器被销毁时加入,或者只存在于整个程序执行过程中。

另外,要提高可移植性,可以使用boost::线程库和boost的条件变量,而不是原始Windows事件。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/11777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档