Выполнение операции с интервалом - PullRequest
1 голос
/ 22 июня 2009

Я хочу выполнить действие в определенное время, например, событие. Я разобрался, как делать каждые n секунд, а не 1,5 секунд. Вот что у меня есть. Подскажите пожалуйста, как справиться с моим делом:

void Publish()
{
    static  int local_time=time(NULL);

     int current_time = time (NULL);
     if((current_time+PUBLISH_TIMEOUT)>local_time)
      {
           fireEvent();
            local_time=current_time;
      } 
}

Ответы [ 7 ]

1 голос
/ 22 июня 2009

gettimeofday() возвращает микросекунды, так что вы можете использовать его вместо time() - см. Определение struct timeval, эта функция заполняет.

Проверьте man gettimeofday для деталей.

0 голосов
/ 23 июня 2009

@ puzzlecracker

Не беспокоит ли загрузка процессора? Ваша программа постоянно проверяет состояние ненужное количество раз. Я бы использовал usleep (), когда он отсутствует:

...

 if(TIMEOUT < time_diff)
{
    cout<<TIMEOUT <<" seconds...\n";
    msec_base=now;

    return 1;
} else usleep(10);

...

Это дает время для других процессов и не влияет на скорость отклика вашего кода.

Еще лучшим решением было бы использование clock_nanosleep () с другим подходом, например, с многопоточным таймером.

0 голосов
/ 22 июня 2009

Я знаю, что это не на основе секунды, но вы можете использовать регистр rdtsc в зависимости от вашего процессора ... Подробнее здесь (для измерения промежутков времени в Linux)

0 голосов
/ 22 июня 2009

Если это C, почему бы не использовать setitimer () и SIGALRM ?

Что setitimer () делает это, через определенный интервал (который можно указать с точностью до миллисекунды) запускает сигнал SIGALRM. Затем вы можете настроить свою программу так, чтобы она имела функцию, которая реагирует на этот сигнал.

Функция alarm () выполняет ту же функцию, что и setitimer (), но alarm () работает только с интервалами в 1 секунду (не 1,5 секунды и т. Д.) для того, как обрабатывать прерывание. Используя этот метод, вы можете сэкономить много времени для расчета кода.

0 голосов
/ 22 июня 2009

Для этого вы можете использовать boost :: asio, см. Документацию здесь:

http://think -async.com / ASIO / boost_asio_1_4_1 / DOC / HTML / boost_asio / ссылка / deadline_timer.html

0 голосов
/ 22 июня 2009

Полное решение, основанное на ответе Ника:

#include <sys/time.h>
#include <iostream>
#include <cstdlib>

using namespace std;

int TOTAL_PROCESSES;
double TIMEOUT;
int process()
{

    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);

    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    double time_diff=seconds+ useconds/100000.0;

    if(TIMEOUT < time_diff)
    {
        cout<<TIMEOUT <<" seconds...\n";
        msec_base=now;

        return 1;
    }
     return 0;

}

int main(int argc, char** argv)
{
    if(argc < 3)
    {
        cout<<"Error: missing TIMOUT and total time to fire\n";
        return -1;

    }

    TIMEOUT       = atof(argv[1]);
    TIMES_TO_FIRE = atoi(argv[2]);

    cout << "INFO: TIMEOUT="<<TIMEOUT<<", TIMES_TO_FIRE ="<< TIMES_TO_FIRE <<endl; 


    int i=0;
    while (i< TIMES_TO_FIRE)
      i+=process();

    return 0;
}
0 голосов
/ 22 июня 2009

Возвращает время ожидания с момента запуска приложения в миллисекундах. Он использует часы машины, поэтому вполне возможно, что изменение времени на часах во время работы приложения запутает его. В вашем случае я бы добавил время расписания к моему объекту события и сработал, когда время расписания <= msec () </p>

 clock_t msec() {
    static struct timeval msec_base;
    struct timeval now;

    long seconds, useconds; 
    if (!msec_base.tv_usec)
        gettimeofday(&msec_base, NULL);
    gettimeofday(&now, NULL);

    seconds  = now.tv_sec  - msec_base.tv_sec;
    useconds = now.tv_usec - msec_base.tv_usec;

    return ((seconds) * 1000 + useconds/1000.0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...