Reputation: 461
I want to run a C program in a specific duration. After this time the program should be terminated. I searched some documents about it but many of them use sleep
function. I don't want to use it. I want to check the current time whether it is bigger than the target time in an infinite loop.
For example below code , my target time is 5 and when running time duration is bigger than the 5, the program should be terminated.
But the code causes an infinite loop. How can I solve this problem?
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(&sev, 0, sizeof(struct sigevent));
memset(&trigger, 0, sizeof(struct itimerspec));
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = &thread_handler;
sev.sigev_value.sival_ptr = &info;
timer_create(CLOCK_REALTIME, &sev, &timerid);
trigger.it_value.tv_sec = 5;
timer_settime(timerid, 0, &trigger, NULL);
timer_gettime(timerid,&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);
}
}
}
Upvotes: 2
Views: 612
Reputation: 60056
If you want to check and compare in a busy loop, you can simply call clock_gettime
and completely avoid timers.
The whole point of a timer is to avoid such busy loops.
In your case your main thread can simply pause and you can exit from the thread_handler function, which is run on a dedicated thread by the timer 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(&sev, 0, sizeof(struct sigevent));
memset(&trigger, 0, sizeof(struct itimerspec));
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = &thread_handler;
sev.sigev_value.sival_ptr = &info;
if(0>timer_create(CLOCK_REALTIME, &sev, &timerid)) return perror("timer_create"),1;
trigger.it_value.tv_sec = 5;
if(0>timer_settime(timerid, 0, &trigger, NULL)) return perror("timer_settime"),1;
pause();
}
If you still want to busy check, you need to have the timer_gettime
in the waiting loop. Calling it just once won't make the trigger
object auto-update on its own.
Upvotes: 2