开发者

C++ main loop timer

My C++ program has a main loop which runs until the program says it's done. In the main loop I want to be able to make certain things happen at certain time intervals. Like this:

int main()
{
    while(true)
    {
        if(ThirtySecondsHasPassed())
        {
            doThis();
        }
        doEverythingElse();
    }
    return 0;
}

In that case, I would want doThis() to be called every thirty seconds, and if 开发者_JS百科it doesn't need to be called, allow the main loop to continue and process everything else.

How can I do this? Also keep in mind that this program is meant to run continually for days, weeks, even months.


Here's a more general class, where you can have seperate timers.

class Timer{
public:
    Timer(time_type interval) : interval(interval) {
        reset();
    }

    bool timedOut(){
        if(get_current_time() >= deadline){
            reset();
            return true;
        }
        else return false;
    }

    void reset(){
        deadline = get_current_time() + interval;
    }

private:
    time_type deadline;
    const time_type interval;
}


Probably the largest overkill yet, but what about Boost.Asio?

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

void doThisProxy(const boost::system::error_code& /*e*/,
    boost::asio::deadline_timer* t)
{
  doThis();
  t->expires_at(t->expires_at() + boost::posix_time::seconds(30));
  t->async_wait(boost::bind(doThisProxy, boost::asio::placeholders::error, t));
}

int main()
{
  boost::asio::io_service io;

  boost::asio::deadline_timer t(io, boost::posix_time::seconds(30));
  t.async_wait(boost::bind(doThisProxy, boost::asio::placeholders::error, &t));

  io.run();
}


if your program is going to be compiled and runned in a windows system you can also use some windows handlers like this :

SetTimer(hwnd,             // handle to main window 
IDT_TIMER1,            // timer identifier 
30000,                 // 10-second interval 
(TIMERPROC) NULL);     // no timer callback 

while (1)
{
    if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        doeverythingelse();                   
    }

    if (WM_QUIT == msg.message)
    {
        break;
    }
    if(WM_TIMER == msg.message)
    {
         if(IDT_TIMER1 == msg.wParam)
              do30secInterval();
    }               
}

you can also pass some function as the last parameter of SetTimer so that the whenever timer ticks it calls your function itself.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜