Реализация интервального таймера с минимальными издержками на C ++ в Linux

0

Я пытаюсь реализовать фоновое пользовательско-космическую программу, которая будет выполнять различные задачи и вычисления каждые 100 мс в Linux. Я могу сделать это, используя сигнал тревоги в Linux, и следующая структура - это способ, которым я выполнил свой таймер.

void timer_handler (int signum){
    printf("In timer handler!\n");
}

int main (){

    struct sigaction s_action;
    struct itimerval timer;

    /* Set Up a Timer */
    /* Install timer_handler as the signal handler for SIGVTALRM. */
    memset (&s_action, 0, sizeof (s_action));
    s_action.sa_handler = &timer_handler;
    sigaction (SIGVTALRM, &s_action, NULL);

    /* Timer configuration for 100ms */
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = 100000;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 100000;

    /* Set up the timer */
    setitimer (ITIMER_VIRTUAL, &timer, NULL);

    while(1);
}

Однако этот подход не является оптимальным способом выполнения (с точки зрения производительности) этого из-за бесконечного цикла. Это значительно увеличивает загрузку процессора. После того, как он начинает работать в фоновом режиме, производительность моих других программ ухудшается с ростом на 15%.

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

  • 1
    Если вы хотите, чтобы ваша программа спала, почему бы не вызвать sleep ()?
  • 0
    Сначала я попробовал спать, но не получилось. Используя sleep () или nanosleep (), мой обработчик таймера никогда не срабатывает. Из справочной страницы alarm (2) я прочитал, что sleep () может мешать сигналу SIGALRM.
Теги:
timer
overhead

1 ответ

0
Лучший ответ

Время чтения (7), сигнал (7), timerfd_create (2), опрос (2), нанослое (2) и расширенное программирование на Linux.

Ваш обработчик сигнала некорректен (он не должен вызывать printf, он может write).

Вы могли бы

while(1) poll(NULL, 0, 1);

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

Я предполагаю, конечно, что вы достаточно уверены, что каждая периодическая задача длится намного меньше, чем период. (например, для каждой задачи требуется не более 50 миллисекунд, но имеет период 100 миллисекунд).

  • 1
    Я думаю, что моя проблема была в основном из-за флага (ITIMER_VIRTUAL), который я использовал с setitimer, который ведет обратный отсчет только тогда, когда процесс активен. Переключение на ITIMER_REAL и опрос файлового дескриптора NULL, как вы предложили, похоже, приводит к очень низким издержкам для интервала 100 мс. Большое спасибо за ссылки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню