Время подсчета с помощью таймера в C

#c #time #timer #posix

#c #время #таймер #posix

Вопрос:

Я хочу запустить программу на C в течение определенного времени. По истечении этого времени программа должна быть завершена. Я искал некоторые документы об этом, но многие из них используют sleep функцию. Я не хочу его использовать. Я хочу проверить текущее время, является ли оно больше целевого времени в бесконечном цикле.

Например, в приведенном ниже коде мое целевое время равно 5, и когда продолжительность времени выполнения превышает 5, программа должна быть завершена.

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

 void thread_handler(union sigval sv) {
    char *s = sv.sival_ptr;
    /* Will print "5 seconds elapsed." */
    puts(s);
}

int main(void) {
    char info[] = "5 seconds elapsed.";
    timer_t timerid;
    struct sigevent sev;
    struct itimerspec trigger;
    struct itimerspec triggerAfter;

    memset(amp;sev, 0, sizeof(struct sigevent));
    memset(amp;trigger, 0, sizeof(struct itimerspec));

    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = amp;thread_handler;
    sev.sigev_value.sival_ptr = amp;info;

    timer_create(CLOCK_REALTIME, amp;sev, amp;timerid);

    trigger.it_value.tv_sec = 5;

    timer_settime(timerid, 0, amp;trigger, NULL); 

    timer_gettime(timerid,amp;trigger);
    while (1) {
        if ((int)trigger.it_value.tv_sec > 5) { //checking the current time is bigger than the target time, it it is then exit from the program
            timer_delete(timerid);
            exit(0);
        }
    }
}
  

Ответ №1:

Если вы хотите проверить и сравнить в цикле занятости, вы можете просто вызвать clock_gettime и полностью избежать таймеров. Весь смысл таймера заключается в том, чтобы избежать таких циклов занятости.

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

 #include <time.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void thread_handler(union sigval sv) {
    char *s = sv.sival_ptr;
    /* Will print "5 seconds elapsed." */
    puts(s);
    exit(0);
}

int main(void) {
    char info[] = "5 seconds elapsed.";
    timer_t timerid;
    struct sigevent sev;
    struct itimerspec trigger;
    struct itimerspec triggerAfter;

    memset(amp;sev, 0, sizeof(struct sigevent));
    memset(amp;trigger, 0, sizeof(struct itimerspec));

    sev.sigev_notify = SIGEV_THREAD;
    sev.sigev_notify_function = amp;thread_handler;
    sev.sigev_value.sival_ptr = amp;info;

    if(0>timer_create(CLOCK_REALTIME, amp;sev, amp;timerid)) return perror("timer_create"),1;

    trigger.it_value.tv_sec = 5;

    if(0>timer_settime(timerid, 0, amp;trigger, NULL)) return perror("timer_settime"),1;

    pause();

}
  

Если вы все еще хотите проверить занятость, вам необходимо иметь timer_gettime в цикле ожидания. Вызов его только один раз не приведет trigger к автоматическому обновлению объекта самостоятельно.