Таймер основного цикла C

#c #loops #time

Вопрос:

В моей программе на C есть основной цикл, который выполняется до тех пор, пока программа не скажет, что это сделано. В основном цикле я хочу, чтобы определенные вещи происходили через определенные промежутки времени. Подобный этому:

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

В этом случае я бы хотел, чтобы doThis() вызывался каждые тридцать секунд, и если его не нужно вызывать, позвольте основному циклу продолжить и обработать все остальное.

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

Комментарии:

1. У программы постоянно есть работа, которую нужно выполнить, или вы хотите, чтобы она спала до тех пор, пока не появится следующая задача?

2. в программе постоянно есть над чем работать.

3. Понадобится ли вам это для работы в Windows, *nix или кросс-платформе ?

Ответ №1:

Вот более общий класс, в котором у вас могут быть отдельные таймеры.

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

Комментарии:

1. Возможно, потребуется немного подправить, но это дает основу для того, что вы, возможно, захотите использовать.

2. Милая, похоже, это послужит моим целям.

Ответ №2:

Возможно, это пока самый большой перерасход, но как насчет 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_codeamp; /*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, amp;t));

  io.run();
}
 

Ответ №3:

если ваша программа будет скомпилирована и запущена в системе Windows, вы также можете использовать некоторые обработчики Windows, подобные этому :

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

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

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

вы также можете передать некоторую функцию в качестве последнего параметра SetTimer, чтобы всякий раз, когда таймер тикает, он вызывал саму вашу функцию.

Комментарии:

1. кажется, есть какой-то эквивалент для подглядывания в том, что я не проверял их сам, вы можете попробовать их.