Пробуждение boost :: sleep timer и сброс его на 0 в C ++ - PullRequest
3 голосов
/ 07 сентября 2011

Мне требуется сигнал сердцебиения каждые 10 секунд или около того.Чтобы реализовать это, я создал класс со следующим конструктором:

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)));
}

, который вызывает следующий метод в новом потоке:

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

. Это вызывает сердцебиение без каких-либо проблем.Однако я хотел бы иметь возможность сбросить таймер сна обратно на ноль.Есть ли простой способ сделать это, или я должен использовать что-то другое, чем

 boost::this_thread::sleep

для сна?


ОС: Redhat

IDE: Eclipse

Язык кода: C ++


РЕДАКТИРОВАТЬ:

Я смотрел на использование

m_pHBThread->interrupt();

И, похоже, япосле, так что спасибо!

Ответы [ 3 ]

5 голосов
/ 07 сентября 2011

Это похоже на то, что делает асинхронный таймер.Поскольку вы уже используете boost, возможно, имеет смысл использовать собственные асинхронные таймеры boost в долгосрочной перспективе?

#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
[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...
1 голос
/ 07 сентября 2011

Возможно, вы можете использовать interrupt () для этого.

0 голосов
/ 07 сентября 2011

Ну, не очень эффективно запускать новую ветку каждый раз, когда у вас бьется сердце ... Я сделал бы это вместо этого с единственным потоком и сном в этом. Если вам нужно изменить частоту сердечных сокращений, вы можете прервать текущий поток и запустить новый с новым временем ожидания. Для этого вы можете использовать boost :: thread и сигнал прерывания.

РЕДАКТИРОВАТЬ: смотрите здесь информацию о буст-потоках: управление буст-потоками

если вы хотите сбросить время на ноль и немедленно выполнить свой код, тогда вызовите его внутри функции catch :: thread_interrupted ...

РЕДАКТИРОВАТЬ 2: Я не смотрел должным образом на код, и я предположил, что там была общая ошибка запуска нового потока для каждого удара сердца ... извините, моя ошибка ... Я думаю, мне не нравится факт, что имя потока: TimerStart ()
В любом случае, я думаю, что использование interrupt () и его перехват должны работать, если вам нужно сразу же выполнить биение сердца.

...