简体   繁体   中英

Waking a boost::sleep timer and reset it to 0 in C++

I require a heartbeat signal every 10 seconds or so. To implement this I have produced a class with the following constructor:

HeartBeat::HeartBeat (int Seconds, MessageQueue * MsgQueue)
{
TimerSeconds = Seconds;
    pQueue = MsgQueue;
    isRunning = true;
    assert(!m_pHBThread);
    m_pHBThread = shared_ptr<thread>(new thread(boost::bind(&HeartBeat::TimerStart,this)));
}

Which calls the following method in a new thread:

void HeartBeat::TimerStart ()
{
while (1)
{
    cout << "heartbeat..." << endl;
    boost::this_thread::sleep(boost::posix_time::seconds (TimerSeconds));
    addHeartBeat();
}
}

This produces a heartbeat with out any issues. However I would like to be able to reset the sleep timer back to zero. Is there a simple way of doing this, or should I use something other than

 boost::this_thread::sleep

for my sleep?


OS: Redhat

IDE: Eclipse

Code language: C++


EDIT:

I have looked at using

m_pHBThread->interrupt();

And it seems to be what I'm after, so thank you!

This sounds exactly like what asynchronous timer does. Since you're using boost already, perhaps it makes sense to use boost's own async timers in the long run?

#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
#include <boost/asio.hpp>
boost::posix_time::ptime now()
{
        return boost::posix_time::microsec_clock::local_time();
}
class HeartBeat {
    boost::asio::io_service ios;
    boost::asio::deadline_timer timer;
    boost::posix_time::time_duration TimerSeconds;
    boost::thread thread;
 public:
    HeartBeat(int Seconds) : ios(), timer(ios),
        TimerSeconds(boost::posix_time::seconds(Seconds))
    {
        reset(); // has to start timer before starting the thread
        thread = boost::thread(boost::bind(&boost::asio::io_service::run,
                                           &ios));
    }
    ~HeartBeat() {
        ios.stop();
        thread.join();
    }
    void reset()
    {
        timer.expires_from_now(TimerSeconds);
        timer.async_wait(boost::bind(&HeartBeat::TimerExpired,
                        this, boost::asio::placeholders::error));
    }
    void TimerExpired(const boost::system::error_code& ec)
    {
        if (ec == boost::asio::error::operation_aborted) {
           std::cout << "[" << now() << "] timer was reset" << std::endl;
        } else {
           std::cout << "[" << now() << "] heartbeat..." << std::endl;
           reset();
        }
    }
};
int main()
{
    std::cout << "["  << now() << "] starting up.\n";
    HeartBeat hb(10);
    sleep(15);
    std::cout << "["  << now() << "] Resetting the timer\n";
    hb.reset();
    sleep(15);
}

test run:

~ $ ./test
[2011-Sep-07 12:08:17.348625] starting up.
[2011-Sep-07 12:08:27.348944] heartbeat...
[2011-Sep-07 12:08:32.349002] Resetting the timer
[2011-Sep-07 12:08:32.349108] timer was reset
[2011-Sep-07 12:08:42.349160] heartbeat...

也许您可以使用interrupt()来执行此操作。

Well, it is not very efficient to launch a new thread every time you have an heart beat... I'd do it instead with a single thread and a sleep inside it. If you need to change the heart beat frequency then you can kill the current thread and start a new one with a new sleep time. You can use the boost::thread and the interrupt signal for this.

EDIT: look here for info on boost threads: boost thread management

if you want to reset the time to zero and execute your code immediately then call it inside the catch for boost::thread_interrupted...

EDIT2: I didn't look properly to the code and I assumed that the common error of launching a new thread for each heart beat was there... sorry, my mistake... I guess I don't like the fact that the thread's name is: TimerStart()
Anyway I think that using the interrupt() and catching it should work if you need to execute the heart beat right away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM