Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a timed loop?

I need to execute some code 1000 times per second. I would like to do something like:

set up interval timer
while (1)
{
   wait for timer
   do something
}

My attempt looks like

// Create timer
timer_t timerid;
struct sigevent sev;

sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGUSR1;

if (timer_create(CLOCK_REALTIME, &sev, &timerid))
{
perror("timer_create");
exit(1);
}

// Every one mSec (10^6 nsec)
struct itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1000000;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 1000000;
if (timer_settime(timerid, 0, &its, NULL))
{
perror("timer_settime");
exit(1);
}

// Create mask to wait for SIGUSR1
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);

while (1)
{
int sig;

// Wait for the timer: Do this loop once per millisecond
sigwait(&set, &sig);

    (do something)
}

When I try this, I just get "User defined signal 1" at the console and my program exits. This is not surprising, as this is the default action for the signal. If I set the signal to SIG_IGN using sigaction(2), I never get to my (do something).

I presume I need to do something with sigaction(2), but I don't see an option for "deliver the signal". I don't want to ignore the signal, or do the default action, or call a function. What's the best way to accomplish my goal?

Or I can just give up and put my (do something) in a function :-)

Edit: I implemented the timerfd idea, and it seems to be working. On to the next bug...

like image 272
rich Avatar asked May 09 '14 06:05

rich


People also ask

What is a timed loop?

The time loop or temporal loop is a plot device in fiction whereby characters re-experience a span of time which is repeated, sometimes more than once, with some hope of breaking out of the cycle of repetition.

How do you make a timed loop in JavaScript?

Use setInterval() to do the timer loop in JavaScript. It will repeat automatically until you clear the interval. setTimeout will execute the code once, after the timeout. setInterval will execute the code forever, in intervals of the provided timeout.


Video Answer


1 Answers

Since you have tagged your question with embedded-linux I assume that portability is not an issue. In that case you might want to have a look at timerfd. It will allow you to use select(2)/poll(2) to receive your timer events. It will also make it easier to combine the interval timer with other event sources such as file descriptors.

like image 191
wkz Avatar answered Sep 29 '22 14:09

wkz