Reputation: 55
I want to call a function, lets say every 10 or 20 seconds. When I searched, I came up with threads and sleep()
method everywhere.
I also checked for time and clock classes in C but I could not find anything helpful specific to my question.
What is the most simple way to call functions periodically?
Upvotes: 3
Views: 12731
Reputation: 409442
A naive solution would be something like this:
/* Infinite loop */
time_t start_time = time(NULL);
for (;;)
{
time_t now = time(NULL);
time_t diff = now - start_time;
if ((diff % 10) == 0)
{
/* Ten seconds has passed */
}
if ((diff % 20) == 0)
{
/* Twenty seconds has passed */
}
}
You might want a flag that tells if the function has been called, or it will be called several times during the single second (diff % 10) == 0
is true.
Please note that this make the assumption that time_t
is an integral type, which for at least 99.999% of of all cases it will be.
It also makes the assumption that time
returns a value with second-only resolution. Which again it will be in at least 99.999% of all cases.
Lastly note that the code show is rather incomplete and was written only as a demonstration. It shouldn't be used "as-is".
Upvotes: 0
Reputation: 236
The most accurate solution in my tests from from the following code#include
<stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <unistd.h>
#include <sys/timerfd.h>
void *
say_hello()
{
int rc, fd;
struct itimerspec myitime;
int64_t buffer;
fd = timerfd_create(CLOCK_REALTIME, 0);
// every 3 seconds
myitime.it_interval.tv_sec = 3;
myitime.it_interval.tv_nsec = 0;
// start at NEXT full second
rc = clock_gettime(CLOCK_REALTIME, &(myitime.it_value));
myitime.it_value.tv_sec += 1;
myitime.it_value.tv_nsec = 0;
rc = timerfd_settime(fd, TFD_TIMER_ABSTIME, &myitime, NULL) ;
// wait for input from fd, then print hello
while(true) {
read(fd, &buffer, 8);
printf("Hello\n");
}
return NULL;
}
int main()
{
say_hello();
// never returns
return 0;
}
Of course say_hello can be spawned as a thread.
The timerfs call, on my unloaded system produces a printer output with a 5.3 microsecond RMS variation. The evtimer method produces a output with a 319 microsecond RMS variation.
Upvotes: 0
Reputation: 6568
Use libevent
, in my opinion, is the cleaner solution because, in the meantime, you can do other operations (even other timed functions)
look at this simple and self explaining example that print out Hello every 3 seconds:
#include <stdio.h>
#include <sys/time.h>
#include <event.h>
void say_hello(int fd, short event, void *arg)
{
printf("Hello\n");
}
int main(int argc, const char* argv[])
{
struct event ev;
struct timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
event_init();
evtimer_set(&ev, say_hello, NULL);
evtimer_add(&ev, &tv);
event_dispatch();
return 0;
}
Upvotes: 4
Reputation: 2092
Simple:
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char** argv)
{
while(1)
{
usleep(20000) ;
printf("tick!\n") ;
}
}
Note that usleep() will of course block :)
Upvotes: 0
Reputation: 129524
Most operating systems have a way to "set an alarm" or "set a timer", which will call a function of yours at a given time in the future. In linux, you'd use alarm
, in Windows you'd use SetTimer
.
These functions have restrictions on what you can do in the function that gets called, and you almost certainly will end up with something that has multiple threads in the end anyway - although the thread may not be calling sleep
, but some wait_for_event
or similar function instead.
Edit: However, using a thread with a thread that contains:
while(1)
{
sleep(required_time);
function();
}
The problem is solved in a very straight forward way to solve the problem, and makes it very easy to handle.
Upvotes: 4
Reputation: 95
Try this:
while(true) {
if(System.getNanotime % 20 == 0) {
myFunction();
}
}
This is in Java-Syntax, i didn't program c since more than 5 years, but maybe it helps you :)
Upvotes: 0