I am trying to implement a timer that continuously counts certain amount of time while the software is running. I wrote a dirty code to try how sys/time.h works.
My understanding is that if I set my it_interval struct to a non-zero value, then the timer should start counting again once it's done counting for the value stored in it_value struct.
However, my code stalls. Could someone tell me what I am missing in my code please? Also, I am using Linux.
#include <sys/time.h>
#include <stdio.h>
#include <stdint.h>
int main(void) {
struct itimerval timer1;
timer1.it_interval.tv_sec = 5;
timer1.it_interval.tv_usec = 0;
timer1.it_value.tv_sec = 5;
timer1.it_value.tv_usec = 0 ;
setitimer(ITIMER_REAL, &timer1, NULL);
printf( "init interval counter: %ld.%ld\n", timer1.it_interval.tv_sec,
timer1.it_interval.tv_usec);
printf( "init value counter: %ld.%ld\n\n", timer1.it_value.tv_sec,
timer1.it_value.tv_usec );
while(1) {
for (int i = 0; i < 100000000000000; i++){
getitimer(ITIMER_REAL, &timer1);
printf( "end interval counter: %ld.%ld\n",
timer1.it_interval.tv_sec, timer1.it_interval.tv_usec);
printf( "end value counter: %ld.%ld\n\n",
timer1.it_value.tv_sec, timer1.it_value.tv_usec );
}
}
return 0;
}
My output (shortened of course) is:
end interval counter: 5.0
end value counter: 0.8821
end interval counter: 5.0Alarm clock
Process returned 142 (0x8E) execution time: 5.033 s
Thank you in advance for your help!
setitimer(ITIMER_REAL,...) causes SIGALRM to be sent to the calling process upon timer expiry. SIGALRM is a normally deadly signal, whose default disposition is to kill the process.
If you want to prevent your process from being killed by this signal, you need to handle it somehow.
Example (prints EXPIRED from the handler every 100ms) based on your code:
#include <sys/time.h>
#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <unistd.h>
void handler(int Sig)
{
(void)Sig;
char msg[]="EXPIRED\n";
ssize_t nwr = write(1,msg,sizeof(msg)-1); (void)nwr;
}
int main(void) {
struct itimerval timer1;
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM,&sa,0);
timer1.it_interval.tv_sec = 0;
timer1.it_interval.tv_usec = 100000;
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 100000 ;
setitimer(ITIMER_REAL, &timer1, NULL);
printf( "init interval counter: %ld.%ld\n", timer1.it_interval.tv_sec,
timer1.it_interval.tv_usec);
printf( "init value counter: %ld.%ld\n\n", timer1.it_value.tv_sec,
timer1.it_value.tv_usec );
while(1) pause();
return 0;
}
Related
I want to trigger a timer each second for 30 seconds. However, the timer is triggered only once and the program stops. How to make the timer run for 30 seconds?
#include <sys/time.h>
#include <signal.h>
void alarmhandler(){
printf("\nTimer triggered");
}
void main(){
struct itimerval timerval;
signal(SIGALRM, alarmhandler);
timerval.it_value.tv_sec = 1;
timerval.it_value.tv_usec = 0;
timerval.it_interval.tv_sec = 30;
timerval.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &timerval, 0);
pause();
}
After receiving a signal your program gets unpaused and it just goes to the end of main() and returns. You need to pause it again, of you want to wait for another signal.
One problem you have is the first timer trigger ends the pause call and your program terminates. The pause command is described like this:
The pause function suspends program execution until a signal arrives whose action is either to execute a handler function, or to terminate the process.
Another problem is that you're using the "interval" incorrectly. That value is supposed to be the number that the timer is reset to if it is a repeating timer. So to trigger every second, you need to set it to 1.
Now, if you want it to run for 30 seconds, you'll need to maintain a counter, and then reset the timer after that counter is finished. Finally, you need to keep re-pausing until enough interrupts have been serviced.
Try this:
#include <sys/time.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
volatile int timer_remain = 30;
void alarmhandler()
{
static struct itimerval notimer = { 0 };
printf( "Timer triggered\n" );
if( --timer_remain == 0 )
{
setitimer( ITIMER_REAL, ¬imer, 0 );
}
}
int main()
{
struct itimerval timerval = { 0 };
timerval.it_value.tv_sec = 1;
timerval.it_interval.tv_sec = 1;
signal( SIGALRM, alarmhandler );
setitimer( ITIMER_REAL, &timerval, 0 );
while( timer_remain > 0 )
{
pause();
}
printf( "Done\n" );
return 0;
}
One last thing to note is that there's no guarantee that the timer will be delivered every second if system load is high.
I have this code that I want to use to handle different signals. I don't know why it never goes to timer_handler2(). It just sticks on timer_handler(). Could someone kindly tell me what I am doing wrong
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
struct timeval theTime;
static int count = 0;
void timer_handler2(int signum) {
printf("timer 2 expired %d times\n", ++count);
}
void timer_handler(int signum) {
printf("timer 1 expired %d times\n", ++count);
}
void timer_handler3(int signum) {
printf("timer 3 expired %d times\n", ++count);
}
int main() {
struct itimerval timer, timer2, timer3, got;
signal(SIGVTALRM, timer_handler2);
signal(SIGALRM, timer_handler);
signal(SIGPROF, timer_handler3);
/* ... and every 1000 msec after that. */
timer2.it_interval.tv_sec = 1;
timer2.it_interval.tv_usec = 0;
/* Configure the timer to expire after 1000 msec... */
timer2.it_value.tv_sec = 1;
timer2.it_value.tv_usec = 0;
/* ... and every 1000 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
/* Configure the timer to expire after 1000 msec... */
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 250000;
/* ... and every 1000 msec after that. */
timer3.it_interval.tv_sec = 1;
timer3.it_interval.tv_usec = 0;
/* Configure the timer to expire after 1000 msec... */
timer3.it_value.tv_sec = 1;
timer3.it_value.tv_usec = 0;
/* Start a real timer. It counts down whenever this process is
executing. */
setitimer(ITIMER_VIRTUAL, &timer2, NULL);
setitimer(ITIMER_REAL, &timer, NULL);
setitimer(ITIMER_PROF, &timer3, NULL);
int counter = 0;
while (1) {
sleep(1);
counter++;
}
return 0;
}
How long are you letting the program run? ITIMER_VIRTUAL only decrements when the program is actually using processor time. Since your program is mostly just sleeping, it's not going to use much processor time. To verify, use the unix 'time' command (or your OS equivalent) to see the real, user and system time used by the program. I'll bet only the real time is enough to activate a timer.
You can try making your VIRTUAL and PROF timer intervals (much) smaller, or do something that doesn't block in your infinite loop (ie: remove the sleep(1) ).
We want to add a timer to our C program under Linux platform.
We are trying to send the packets and we want to find out how many packets get sent in 1 minute. We want the timer to run at the same time as the while loop for sending the packet is being executed. For example:
while(1)
{
send packets;
}
This loop will keep on sending the packets until ctrl-z is pressed. The timer should be used to stop the loop after 60 seconds.
You could do something like this:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
volatile int stop=0;
void sigalrm_handler( int sig )
{
stop = 1;
}
int main(int argc, char **argv)
{
struct sigaction sact;
int num_sent = 0;
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = sigalrm_handler;
sigaction(SIGALRM, &sact, NULL);
alarm(60); /* Request SIGALRM in 60 seconds */
while (!stop) {
send_a_packet();
num_sent++;
}
printf("sent %d packets\n", num_sent);
exit(0);
}
If loop overhead turns out to be excessive, you could amortize the overhead by sending N packets per iteration and incrementing the count by N each iteration.
Just check the time on every iteration of the loop and when 1 minute has elapsed, count how many packets you have sent.
Edit changed to reflect what the question actually asks!
time_t startTime = time(); // return current time in seconds
int numPackets = 0;
while (time() - startTime < 60)
{
send packet
numPackets++;
}
printf("Sent %d packets\n", numPackets);
Can also check this http://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html to set timers which will send signals to your process and you can stop the while loop.
Look at the standard time() function.
Here is code snippet of itimer that can be used for different time intervals on C with linux platform:
#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 1 sec... */
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
/* ... and every 1000 msec after that. */
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
/* Start a virtual timer. It counts down whenever this process is
* executing. */
setitimer (ITIMER_VIRTUAL, &timer, NULL);
/* Do busy work. */
while (1);
sleep(1);
}
hope it will help.
Use wheetimer (and its variant) data structures to implement timers.
man 3 sleep:
NAME
sleep - Sleep for the specified number of seconds
SYNOPSIS
#include < unistd.h >
unsigned int sleep(unsigned int seconds);
Can anybody provide help to stop the signal after certain repetions .Below is the sample code.
I want that after 3 repetitions the signal should be stopped.But currently it is not stopping:
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <errno.h>
#define INTERVAL 1
int g=0;
int howmany = 0;
void exit_func (int i)
{
signal(SIGTERM,exit_func);
printf("\nBye Bye!!!\n");
exit(0);
}
void alarm_wakeup (int i)
{
struct itimerval tout_val;
g++;
printf("\n %d \n",g);
// signal(SIGALRM,alarm_wakeup);
if(g==3)
{
printf("\n %d \n",g);
signal(SIGSTOP,exit_func);
printf("%s",strerror(errno));
}
howmany += INTERVAL;
printf("\n%d sec up partner, Wakeup!!!\n",howmany);
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
}
int main ()
{
struct itimerval tout_val;
tout_val.it_interval.tv_sec = 0;
tout_val.it_interval.tv_usec = 0;
tout_val.it_value.tv_sec = INTERVAL; /* 10 seconds timer */
tout_val.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &tout_val,0);
signal(SIGALRM,alarm_wakeup); /* set the Alarm signal capture */
signal(SIGINT,exit_func);
while (1)
{
//printf("Dd");
}
}
Do not raise SIGSTOP, call exit_func directly.
include the appropriate headers:
#include <stdlib.h> //exit
#include <string.h> //strerror
also, why do you try to set up a signal handler in your exit function? it doesn't make sense.
I want to create a timer in our C program so that it can print the variable after every 1 second.
Can anybody help me in doing this?
Don't use busy waiting, because you've got 100% CPU utilization.
You must use system function which turns process into sleeping mode for example select():
#include <stdio.h>
#include <sys/select.h>
void your_callback()
{
printf("%s\n", __FUNCTION__);
}
int main()
{
struct timeval t;
while (1) {
t.tv_sec = 1;
t.tv_usec = 0;
select(0, NULL, NULL, NULL, &t);
your_callback();
}
return 0;
}
If all you are interested in doing is printing the value of a variable at a one second interval, using time(2) or clock(3) as suggested in the other answers might suffice. In general, I would not recommend these busy-waiting techniques.
If your program is more complex, I suggest you investigate using the alarm(2) or settimer(2) function to asynchronously deliver a signal to your application at a one second interval.
The following example uses select(2) to block indefinitely in order to minimize CPU usage associated with busy-waiting techniques. The blocking select() call is interrupted and returns when a signal is caught. In the case of the SIGALRM signal, the print_variable flag is set and the value of variable is printed.
Example 1: using alarm()
#include <signal.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
volatile unsigned int variable = 0;
volatile unsigned int print_variable = 0;
void alarm_handler(int signum)
{
variable++;
print_variable = 1;
alarm(1);
}
int main()
{
signal(SIGALRM, alarm_handler);
alarm(1);
for (;;)
{
select(0, NULL, NULL, NULL, NULL);
if (print_variable)
{
printf("Variable = %u\n", variable);
}
}
}
Note: Error checking was omitted from the above code for simplicity.
A printf() function could have been called inside the SIGALRM handler, but calling non-reentrant functions in a signal handler is generally discouraged.
A timeout of one second can also be passed to select(), but if it were interrupted by any signal, additional logic is necessary to ensure that the remainder of the one second timeout is honored. Fortunately on Linux, select() modifies the timeout value to reflect the amount of time not slept. This allows interruption cases to be detected followed by subsequent call(s) select() to complete the timeout.
Example 2: using select()
#include <errno.h>
#include <stdio.h>
#include <sys/select.h>
volatile unsigned int variable = 0;
int main()
{
struct timeval tv;
int val;
for (;;)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
do
{
val = select(0, NULL, NULL, NULL, &tv);
} while (val != 0 && errno == EINTR);
printf("Variable = %u\n", ++variable);
}
}
If you want only second precision. Use time(0) which returns current time if time.h is included.
update:
Adding simple example which prints 10 in every second during 20 seconds:
#include <time.h>
#include <stdio.h>
int main()
{
int a = 10;
int num = 20;
int c = time(0);
while(n--)
{
printf("%d\n", a);
while(!(time(0) - c));
c = time(0);
}
return 0;
}
use time(0) see this example
/* timer.c */
#include <stdio.h>
#include <time.h>
void delay_sec( int seconds ){
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC;
while (clock() < endwait) {}
}
int main (void){
time_t rawtime, ini_time, now;
struct tm *ptm;
time ( &ini_time );
for(;;){
time ( &rawtime );
//ptm = gmtime ( &rawtime );
//printf ("%2d:%02d:%02d\n", ptm_2->tm_hour, ptm_2->tm_min, ptm_2->tm_sec);
now = rawtime - ini_time;
ptm = gmtime ( &now );
printf ("%2d:%02d:%02d\n", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
delay_sec(1);
}
return 0;
}
I believe you know 1000 Milliseconds equals to 1 Second.
#include <stdio.h>
#include <time.h>
#define mydelay 1000
void delay(int mseconds)
{
clock_t wait = mseconds + clock();
while (wait > clock());
}
int main()
{
int i=100;
while(1)
{
printf("%d\n",i);
delay(mydelay);
}
return 0;
}
A simple example which prints the value of the variable a for every 1 sec:
#include<stdio.h>
void main(void)
{
int a = 10;
while(a--)
{
printf("Value of a = %d\n", a);
sleep(1);
}
}
Output:
Value of a = 9
...
value of a = 0