Re: precise time values in a daemon.
- From: The Natural Philosopher <tnp@xxxxxxxxxxxxxxx>
- Date: Sat, 19 Mar 2011 17:11:28 +0000
Richard Kettlewell wrote:
The Natural Philosopher <tnp@xxxxxxxxxxxxxxx> writes:
I am wanting to write a daemon to do some monitoring, and I want to
ensure that it does its thing..which may take a variable amount of
time, at precise intervals of - say - 5 minutes.
so
while(1) {do variable time stuff - sleep 5 minutes}
is too imprecise.
But I don't want to waste cycles, checking the time..
Retrieving the current time is actually extremely quick under Linux - it
doesn't even require a system call. If you mean you don't want to poll
for the right time coming round, yeah, that would not be very efficient.
It seems that some combination of alarm() and sleep() would work, butThe default behavior of SIGALRM is to terminate the process, so if you
I a not sure how to set up a signal handler..
is it as simple as
alarm(5 minutes)
pause()
Or do I need to set up a signal handler for the interrupt?
go this route you will need to install a signal handler.
I would also like the daemon to be able to detect and act on kill
signals as well.
If you just want it to exit when SIGTERM is received you don't have to
do anything special; that's the default behavior for SIGTERM. If you
want to do some clean-up before exiting then you will need more...
I would suggest something along these lines:
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
const int interval = 5; /* seconds between scheduled work */
/* empty handler for SIGALRM */
static void alarm_handler(int x) { }
/* handler for fatal signals */
static volatile sig_atomic_t terminated;
static void term_handler(int x) { terminated = 1; }
int main() {
time_t now, next;
sigset_t mask, oldmask;
struct sigaction sa;
/* mask out signals while working */
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
sigaddset(&mask, SIGTERM);
sigaddset(&mask, SIGINT);
if(sigprocmask(SIG_BLOCK, &mask, &oldmask) < 0) {
perror("sigprocmask"); exit(-1);
}
/* install signal handlers */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = alarm_handler;
if(sigaction(SIGALRM, &sa, NULL) < 0) { perror("sigaction"); exit(-1); }
sa.sa_handler = term_handler;
if(sigaction(SIGTERM, &sa, NULL) < 0) { perror("sigaction"); exit(-1); }
if(sigaction(SIGINT, &sa, NULL) < 0) { perror("sigaction"); exit(-1); }
/* set up timing */
time(&now); /* base time */
next = now + interval; /* when to next to scheduled work */
/* main loop */
while(!terminated) {
time(&now);
if(now >= next) {
next += interval;
printf("scheduled work goes here...\n");
} else {
alarm(next - now);
/* atomically restore signals and wait for one to arrive */
sigsuspend(&oldmask);
if(errno != EINTR) { perror("sigsuspend"); exit(-1); }
}
}
printf("shutdown logic goes here...\n");
return 0;
}
The reason for blocking signals and using sigsuspend() instead of
pause() is that the TERM/INT signal could arrive while pause() is not
running and therefore fail to interrupt it.
The reason for not putting the shutdown logic in the signal handler is
that there's almost nothing you can safely do in a signal handler.
I hoped you would jump in with something.
In between the original post and now, I was reading up on this stuff, and coming to a similar conclusion, BUT you have fleshed out the detail.
Well aware of what is safe to do inside interrupts..as you say, set a global flag is about as good as it gets :-)
Is the 'volatile' to indicate it may get affected asynchronously?
I used to do all this stuff in assembler..its curious to see how it works in 'C'
Many thanks.
.
- Follow-Ups:
- Re: precise time values in a daemon.
- From: Richard Kettlewell
- Re: precise time values in a daemon.
- References:
- precise time values in a daemon.
- From: The Natural Philosopher
- Re: precise time values in a daemon.
- From: Richard Kettlewell
- precise time values in a daemon.
- Prev by Date: Re: precise time values in a daemon.
- Next by Date: Re: precise time values in a daemon.
- Previous by thread: Re: precise time values in a daemon.
- Next by thread: Re: precise time values in a daemon.
- Index(es):
Relevant Pages
|