I was looking at this stack exchange question: how to call a function automatically at regular intervals?
And I tried running the code in the first answer
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer expired %d times\n", ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work. */
while (1);
}
I don't understand what it is doing. It appears to print "Alarm Clock" after 2500 milliseconds, but I don't understand how that's possible since there is no print statement to that effect. How do I get it to increment the counter every 2500 milliseconds like its supposed to?
ITIMER_REAL sends SIGALRM not SIGVTALRM.
Change the signal and it'll work.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer expired %d times\n", ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work. */
while (1);
}
(Generally, it's a bad idea to printf in a signal handler since printf isn't async-signal safe, but in your case it shouldn't be dangerous, because you're interrupting regular-context code that is async-signal safe (namely the busy loop). POSIX doesn't appear to guarantee this special exception, though, so to be perfectly safe, you should refrain from making any async-signal unsafe calls in signal handlers and replace the printf with a write(1, ...).)
Related
I know scanf waits for input.
But in this program I have written it is printing
hello in an infinite loop. Its not waiting for me to enter.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include<unistd.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer expired %d times\n", ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM, &sa, NULL);
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work.
*/
int i=0;
while(1){
scanf("%d",&i); //****Not waiting for input****
printf("hello");
}
}
Output :
timer expired 1 times
hello timer expired 2 times
hello timer expired 3 times
hello timer expired 4 times
hello timer expired 5 times
hello timer expired 6 times
hello timer expired 7 times
Why ?
?
The scanf function on POSIX platforms somewhere in its implementation is using the read system call. When the timer signal is happening then the read call will be interrupted and return with an error (EINTR), which in turn leads to scanf returning as well. You can check this by checking what scanf returns. In this case it should return EOF with errno still set to EINTR.
A simple solution to this is to ask the signal to restart the interrupted system call. This is done by adding the SA_RESTART flag in the sigaction structures sa_flags member:
sa.sa_flags = SA_RESTART;
More information can be found in e.g. this POSIX sigaction reference.
Here i am trying achieve a timer say 0-10secs and an interval of 2secs each,so that i need to generate an interrupt # every 2secs(total 5 times) saying 2secs completed. which i have been cross checking in handler() function by using printf(). But i am not able to achieve the desired result.please put me touch if anyone is aware of it.
Thanks in advance.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define SIGTIMER (SIGRTMAX)
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
void handler(int sig, siginfo_t *si, void *uc)
{
printf("Caught signal %d\n", sig);
}
int
main(int argc, char *argv[])
{
timer_t timerid;
struct sigevent sev;
struct itimerspec its;
struct itimerspec oitval;
struct sigaction sa;
/* Establish handler for timer signal */
printf("Establishing handler for signal %d\n", SIGTIMER);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGTIMER, &sa, NULL) == -1)
errExit("sigaction");
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGTIMER;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == 0)
{
printf("timer ID is 0x%lx\n", (long) timerid);
/* Start the timer */
its.it_value.tv_sec = 10;
its.it_value.tv_nsec =0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
if (timer_settime(timerid, 0, &its, &oitval) == -1)
errExit("timer_settime");
}
else
{
errExit("timer_create");
}
return 0;
}
First of all you should properly setup timeouts:
/* Start the timer */
its.it_value.tv_sec = 2;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
it_value is the duration before first triggering, and it_interval is time between all subsequent triggerings. See here. Then, you shouldn't return from main() due it leads to process exit and you won't be able to observe timer ticks. You need to block execution somehow, e.g.
while(1) sleep(INT_MAX);
After each tick sleep() returns with errno set to EINTR so it should we wrapped into loop to allow timer to go ahead. Later you can decide when to leave this loop and exit.
P.S. Using printf() from signal handler is not a good idea. You should be very carefully with what you are doing there. It would be better just to write to some global variable and immediately return. And that var may be tested immediately after sleep() giving you an idea if you should sleep again or return.
I am wondering if there is a way to get every integer second in a c program. I tried to use 'gettimeofday' function to get the current time and then if the current fractional part of second falls into a region (say larger than 0.9 and smaller than 0.1), I rounded the current time into an integer. However, when I run the program, occasionally, there were a few seconds missed. Does anyone have a better solution?
Thanks
I would suggest to use the alarm signal:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
void timer_handler (int signum)
{
struct timeval tval;
gettimeofday(&tval, NULL);
printf("Seconds: %ld\n",tval.tv_sec);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
setitimer (ITIMER_VIRTUAL, &timer, NULL);
while (1);
}
At my Mac (OS X 10.11.5) I get:
./alarm
Seconds: 1468937712
Seconds: 1468937713
Seconds: 1468937714
Seconds: 1468937715
Seconds: 1468937716
Seconds: 1468937717
Seconds: 1468937718
Seconds: 1468937719
Seconds: 1468937720
EDIT
The code above uses the virtual timer, that only ticks als long the thread is running (and thus relies on the busy loop the introduce the high load). Using the real timer allows for reduction of the load:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
void timer_handler (int signum)
{
struct timeval tval;
printf("Foo");
gettimeofday(&tval, NULL);
printf("Seconds: %ld\n",tval.tv_sec);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
sa.sa_mask=0;
sa.sa_flags=0;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGALRM, &sa, NULL);
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer, NULL);
while (1){
pthread_yield_np();
}
}
This approach runs basically the timer handler only. Thus the OS shouldn't care to much about load. However, be aware that hard real-time guarantees one get by OS's real-time features only (if there are any).
I am running the following program which implements a timer. When a thread awake after receiving a signal on condition variable from the previous running thread, it creates a timer and send a signal to the next thread on timer expiration. I want it to run for some time, but the timer stops ticking after some runs.
//Import
#define _POSIX_C_SOURCE 199309
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#define NUM_THREADS 10
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;
pthread_cond_t condA[NUM_THREADS+1] = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t tid[NUM_THREADS];
int state = 0;
static void handler(int sig, siginfo_t *si, void *uc)
{
if(si->si_value.sival_ptr != &timerid){
printf("Stray signal\n");
} else {
//printf("Caught signal %d from timer\n", sig);
}
pthread_cond_signal(&condA[state]);
}
void *threadA(void *data_)
{
int i = 0, s;
long int loopNum, j;
int turn = (intptr_t)data_;
struct timeval tval_result;
// Timer's part starts
struct sigevent sev;
struct itimerspec its;
long long freq_nanosecs;
sigset_t mask;
struct sigaction sa;
// TImer'spart ends
while(1)
{
/* Wait for state A */
pthread_mutex_lock(&mutex);
for (;state != turn;)
{
s = pthread_cond_wait(&condA[turn], &mutex);
if (s != 0)
perror("pthread_cond_wait");
// printf("main(): state = %d\n", state);
}
pthread_mutex_unlock(&mutex);
//do stuff
for(j=0;j<10000;j++)
{//some dummy time consuming works}
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCKID, &sev, &timerid);
/* Start the timer */
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 2000;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &its, NULL);
pthread_mutex_lock(&mutex);
state = (state +1)%NUM_THREADS;
//pthread_cond_signal(&condA[state]);
pthread_mutex_unlock(&mutex);
// Timer's code ends
}
}
int main(int argc, char *argv[])
{
int data = 0;
int err;
while(data < NUM_THREADS)
{
//create our threads
err = pthread_create(&tid[data], NULL, threadA, (void *)(intptr_t)data);
if(err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
// printf("\n Thread created successfully\n");
data++;
}
pthread_exit(NULL);
}
Although no printf statements are executing, why is it freezing after some time?
If no. of timers are limited, what other strategy should I use to redress this issue?
POSIX says:
It is not safe to use the pthread_cond_signal() function in a signal handler that is invoked asynchronously.
Most likely you end up corrupting the state of pthread_cond_wait/pthread_cond_signal and anything can happen.
Don't mix threads and signal handlers, it leads only to madness. There are very few things you're allowed to do inside a signal handler, even fewer that are thread related, it's very hard to ensure that the right thread ends up handling the right signal, etc.
If you're doing threads anyway implement a timer in one thread that calculates how much time it needs to sleep to deliver the next event (don't just hardcode it to your timer period since that will make your timer drift), sleep that much and call pthread_cond_signal.
Also, it's bad form to have naked pthread_cond_signal calls and most often a bug. You might get unlucky and call it just before the other thread does the pthread_cond_wait and your signal will get lost. The normal thing to do is to set a variable (protected by a mutex, that's why pthread_cond_signal wants a mutex) and then signal that the variable is set.
If you think this is too much work, condition variables are probably not the right mechanism in this case and you should use semaphores instead. Incidentally sem_post is legal to call from a signal handler according to POSIX, but I still think it's a bad idea to mix threads with signals.
I am learning how to use RT timers to create a periodic event.
I have trying with this example that is based of the timer_create documentation example.
The behavior expected is produce a periodic event each 5 seconds meanwhile main execution is sleeping for 30 seconds, but I get the follow behavior.
The timer is created and is initialized the main execution sleeps. 5 seconds later the timer event is produced, the respectively handler is call and when the handler function finishes the main execution wakes up and the elapsed time is 5 second but must be 30 seconds.
/* gcc main.c -Wall -Wextra -lrt -o timer */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
/* Macros *********************************************************************/
#define CLOCKID CLOCK_REALTIME
/* Real-time signals number */
#define RT_SIGNAL_NUM SIGRTMIN
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE);} while (0)
#define MAIN_SLEEP 30
#define TIMER_TIME 5
/* Global data ****************************************************************/
struct itimerspec gIts;
timer_t gTimerId;
/* Functions ******************************************************************/
static void handler(int sig, siginfo_t *si, void *uc)
{
int or;
timer_t *tidp;
/* Note: calling printf() from a signal handler is not
strictly correct, since printf() is not async-signal-safe;
see signal(7) */
printf("Caught signal %d\n", sig);
signal(sig, SIG_IGN);
}
void main(int argc, char *argv[])
{
struct sigevent sev;
long long freq_nanosecs;
sigset_t mask;
struct sigaction sa;
time_t begin, end;
double time_spent;
(void) argc;
(void) argv;
/* Establish handler for Real-time signal */
printf("Establishing handler for signal %d\n", RT_SIGNAL_NUM);
/* If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of
* sa_handler) specifies the signal-handling function for signum.
*/
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
/* the Signal no would be masked. */
sigemptyset(&sa.sa_mask);
/* Change the action taken by a process on receipt of a specific signal. */
if (-1 == sigaction(RT_SIGNAL_NUM, &sa, NULL))
{
errExit("sigaction");
}
/* Configure timer:
* SIGEV_SIGNAL: Upon timer expiration, generate the signal sigev_signo for
* the process.
*/
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = RT_SIGNAL_NUM;
sev.sigev_value.sival_ptr = &gTimerId;
/* Create and init the timer */
if (-1 == timer_create(CLOCKID, &sev, &gTimerId))
{
errExit("timer_create");
}
printf("timer ID is 0x%lx\n", (long) gTimerId);
/* Start the timer */
gIts.it_value.tv_sec = TIMER_TIME ;
gIts.it_value.tv_nsec = 0;
gIts.it_interval.tv_sec = TIMER_TIME;
gIts.it_interval.tv_nsec = 0;
if (-1 == timer_settime(gTimerId, 0, &gIts, NULL))
{
errExit("timer_settime");
}
/* Sleep for a while; meanwhile, the timer may expire multiple times */
struct itimerspec currTime;
printf("Main Sleep for %d seconds\n", MAIN_SLEEP);
begin = time(NULL);
sleep(MAIN_SLEEP);
end = time(NULL);
printf("Main Wake up\n");
time_spent = (double)(end - begin);
timer_gettime(gTimerId, &currTime);
printf("Main sleep elapsed time = %f s %d %d\n",time_spent);
printf("Timer time = %ld s\n",currTime.it_value.tv_sec);
exit(EXIT_SUCCESS);
}
This is the execution output:
Establishing handler for signal 34
timer ID is 0x9522008
Main Sleep for 30 seconds
Caught signal 34
Main Wake up
Main sleep elapsed time = 5.000000 s
Timer time = 4 s
Can someone help me to figure out what happen here?
Thanks in advance.
When the signal is generated, the sleep function is interrupted and returns immediately. To quote the man page for sleep
The sleep() function suspends execution of the calling thread until
either [the time has] elapsed or a signal is delivered to the
thread and its action is to invoke a signal-catching function or to
terminate the thread or process.
Fortunately, the return value from the sleep function is the amount of time left to sleep, so you can simply call sleep in a loop like this
int t = 30;
while ( t > 0 )
t = sleep( t );