Is there an example of a working timer that executes some function every x amount seconds using C.
I'd appreciate an example working code.
Is there an example of a working timer that executes some function every x amount seconds using C.
I'd appreciate an example working code.
You could spawn a new thread:
void *threadproc(void *arg)
{
while(!done)
{
sleep(delay_in_seconds);
call_function();
}
return 0;
}
...
pthread_t tid;
pthread_create(&tid, NULL, &threadproc, NULL);
Or, you could set an alarm with alarm(2)
or setitimer(2)
:
void on_alarm(int signum)
{
call_function();
if(!done)
alarm(delay_in_seconds); // Reschedule alarm
}
...
// Setup on_alarm as a signal handler for the SIGALRM signal
struct sigaction act;
act.sa_handler = &on_alarm;
act.sa_mask = 0;
act.sa_flags = SA_RESTART; // Restart interrupted system calls
sigaction(SIGALRM, &act, NULL);
alarm(delay_in_seconds); // Setup initial alarm
Of course, both of these methods have the problem that the function you're calling periodically needs to be thread-safe.
The signal method is particularly dangerous because it must also be async-safe, which is very hard to do -- even something as simple as printf
is unsafe because printf
might allocate memory, and if the SIGALRM
interrupted a call to malloc
, you're in trouble because malloc
is not reentrant. So I wouldn't recommend the signal method, unless all you do is set a flag in the signal handler which later gets checked by some other function, which puts you back in the same place as the threaded version.
There are various legacy ways to do this using interval timers and signals, but I'm going to present two modern approaches:
The POSIX timer_create
function creates a timer that can be configured to deliver a one-off or periodic notification when the timer expires. When creating the timer, you can request either delivery via a signal or in a new thread. Since using signals correctly is complicated (there are strict rules about what you can and cannot do from a signal handler, and breaking the rules often "seems to work" until you get unlucky), I would recommend using thread-based delivery.
This is really as easy as it sounds. Make a new thread that goes into a loop sleeping and doing whatever you need done every time the desired time has elapsed.
If we do not want threads, we could use sleep
int time = 10;
printf("time: %ds\n", time);
int i = 0;
while(i<time) {
printf("doing stuff in duration %d\n", i);
//stuff();
sleep(1);
i++;
}
The stuff is started every 1s, so we hope it can be done in this duration, otherwise it must take care of resources.
IMO, in this case, you can utilize gettimeofday()
into algorithm like:
use such a while(1)
that counts time difference between current time and last_execution_time, everytime the difference reach 1 seconds, update the last_execution_time and call the function that supposed to run in every 1 second.
#include <stdio.h>
#include <sys/time.h>
#DEFINE DESIRED_INTERVAL 1 //1 second
int get_tv_cur_minus_given(struct timeval *tv, struct timeval *tp_given, int *sign)
{
struct timeval tp_cur;
gettimeofday(&tp_cur,NULL);
tv->tv_sec = tp_cur.tv_sec - tp_given->tv_sec;
tv->tv_usec = tp_cur.tv_usec - tp_given->tv_usec;
if(tv->tv_sec > 0) {
*sign = 1;
if(tv->tv_usec < 0) {
tv->tv_sec--;
tv->tv_usec = 1000000 + tv->tv_usec;
}
}else
if(tv->tv_sec == 0) {
if(tv->tv_usec == 0)
*sign = 0;
else
if(tv->tv_usec < 0) {
*sign = -1;
tv->tv_usec *= -1;
}else
*sign = 1;
}else {
*sign = -1;
if(tv->tv_usec > 0) {
tv->tv_sec++;
tv->tv_usec = 1000000 - tv->tv_usec;
}else
if(tv->tv_usec < 0)
tv->tv_usec *= -1;
return 0;
}
}
int main()
{
struct timeval tv_last_run;
struct timeval tv_diff;
int sign;
while(true)
{
get_tv_cur_minus_given(&tv_diff, &tv_last_run, &sign);
if(tv_diff.tv_sec > DESIRED_INTERVAL)
{
gettimeofday(&tv_last_run,NULL);
printf("\ncall the func here");
}
}
return 0;
}
In case you need different thread out of main thread, move the lines inside main() into a function pointer and pass it through pthread_create function, eg :
void *threadproc(void *arg)
{
while(1)
{
//put the same lines as inside main() function in above code snippet. .
}
}
pthread_create(&tid, NULL, &threadproc, NULL);
© 2022 - 2024 — McMap. All rights reserved.
man 3 sleep
: Just write a loop that 1) does something, 2) sleeps "n" seconds – Oversell