run an infinite loop for a while in c - c

I want to run an infinite loop for a while. Basically, i want to have something like this
//do something
while(1){
//do some work
}
//do some other thing
but i want the running time of the loop to be fixed, example, the loop could be running for 5 seconds.
Do somebody have an idea?

Just do sleep(5) (include unistd.h). You can use it like this:
// do some work here
someFunction();
// have a rest
sleep(5);
// do some more work
anotherFunction();
If you're doing work inside the loop, you can do (include time.h):
// set the end time to the current time plus 5 seconds
time_t endTime = time(NULL) + 5;
while (time(NULL) < endTime)
{
// do work here.
}

Try using clock().
#include <time.h>
clock_t start = clock();
while (1)
{
clock_t now = clock();
if ((now - start)/CLOCKS_PER_SEC > 5)
break;
// Do something
}

First of all, consider using the sleep function if possible. If you have to do actual work for a specified time period, which I find unlikely, the following ugly solution would work:
#include <signal.h>
int alarmed = 0;
void sigh(int signum) {
alarmed = 1;
}
int main(void){
/* ... */
signal(SIGALRM, &sigh);
alarm(5); // Alarm in 5 seconds
while(!alarmed) {
/* Do work */
}
/* ... */
}
A solution using time.h would also be possible, and perhaps simpler and/or more accurate, depending on context:
#include <time.h>
int main(void){
/* ... */
clock_t start = clock();
while(clock() - start < 5 * CLOCKS_PER_SEC) {
/* Do work */
}
/* ... */
}

Pseudo-code:
starttime = ...;
while(currentTime - startTime < 5){
}

If you don't want to call a time getting function each time through the loop and are on a system that has alarm (POSIXes like Unix, Linux, BSD...) you can do:
static volatile int timeout = 0;
void handle_alrm(int sig) {
timeout = 1;
}
int main(void) {
signal(SIGALRM, handle_alrm);
...
timeout = 0;
alarm(5);
while (!timeout) {
do_work();
}
alarm(0); // If the signal didn't fire yet we can turn it off now.
...
Signals can have other side effects (like kicking you out of system calls). You should look into these before relying on them.

Not tested; resolution is very coarse.
#include <time.h>
#define RUNTIME 5.0 /* seconds */
double runtime = 0;
double start = clock(); /* automatically convert clock_t to double */
while (runtime < RUNTIME / CLOCKS_PER_SEC) {
/* work */
runtime = clock() - start;
}
If /* work */ takes more than 5 seconds, the loop will take more than 5 seconds.
If /* work */ takes 1.2 seconds, the loop will execute approximately 5 times for a total of 6 seconds

Related

Running a while loop for 10 seconds [duplicate]

This question already has answers here:
How to use timer in C?
(4 answers)
Closed 2 years ago.
I need to run a while loop in C for exactly 10 seconds. I tried this:
clock_t start = clock();
while( ( clock() - start ) < ( 10 * CLOCKS_PER_SEC ) ) {
work..
}
but it is not working.
Seems like what you may really want is an actual timer so that when a specified time interval passes a function is called. In that function you can handle disconnecting clients from the server.
See: https://programming.vip/docs/linux-c-language-timer.html
You should be able to modify this example to do as you need:
#include<stdio.h>
#include<signal.h>
#Include<sys/time.h>//itimerval structure definition
int handle_count=0;
void set_time(void)
{
struct itimerval itv;
itv.it_interval.tv_sec=10;//Load automatically and then respond every 10 seconds
itv.it_interval.tv_usec=0;
itv.it_value.tv_sec=5;//Time of First Timing
itv.it_value.tv_usec=0;
setitimer(ITIMER_REAL,&itv,NULL);
}
void alarm_handle(int sig)
{
handle_count++;
printf("have handle count is %d\n",handle_count);
}
void main(void)
{
struct itimerval itv;
signal(SIGALRM,alarm_handle);
set_time();
while(1){
getitimer(ITIMER_REAL,&itv);
printf("pass second is %d\n",(int)itv.it_value.tv_sec);
sleep(1);
}
return;
}
Some man page links:
https://linux.die.net/man/2/getitimer
https://linux.die.net/man/2/alarm
Another example from another StackOverflow answer:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
static unsigned int pass_value_by_pointer = 42;
void Timer_has_expired(union sigval timer_data)
{
printf("Timer expiration handler function; %d\n", *(int *) timer_data.sival_ptr);
}
int main(void)
{
struct sigevent timer_signal_event;
timer_t timer;
struct itimerspec timer_period;
printf("Create timer\n");
timer_signal_event.sigev_notify = SIGEV_THREAD;
timer_signal_event.sigev_notify_function = Timer_has_expired; // This function will be called when timer expires
// Note that the following is a union. Assign one or the other (preferably by pointer)
//timer_signal_event.sigev_value.sival_int = 38; // This argument will be passed to the function
timer_signal_event.sigev_value.sival_ptr = (void *) &pass_value_by_pointer; // as will this (both in a structure)
timer_signal_event.sigev_notify_attributes = NULL;
timer_create(CLOCK_MONOTONIC, &timer_signal_event, &timer);
printf("Start timer\n");
timer_period.it_value.tv_sec = 1; // 1 second timer
timer_period.it_value.tv_nsec = 0; // no nano-seconds
timer_period.it_interval.tv_sec = 0; // non-repeating timer
timer_period.it_interval.tv_nsec = 0;
timer_settime(timer, 0, &timer_period, NULL);
sleep(2);
printf("----------------------------\n");
printf("Start timer a second time\n");
timer_settime(timer, 0, &timer_period, NULL);
sleep(2);
printf("----------------------------\n");
printf("Start timer a third time\n");
timer_settime(timer, 0, &timer_period, NULL);
printf("Cancel timer\n");
timer_delete(timer);
sleep(2);
printf("The timer expiration handler function should not have been called\n");
return EXIT_SUCCESS;
}
Please specify what is not working. I'm gonna guess:
On Debian 10 the correct macro is CLOCKS_PER_SEC. But maybe Ubuntu added CLOCKS_PER_SECOND as an alias, in which case that is not the problem you have.
The way you implemented your timer, you may loop further than 10 seconds (if your "work" time is not a divisor of 10s).
If that is your actual issue, you should check asynchronous tasks and signals.
This way you can have one process (or thread) making your initial work in a infinite loop, and a second process notifying the first one (eg. with a signal) after 10 seconds elapsed. But that will require a much more complex code!
I hope I brought you some help, but if I did not try to be more precise in your question.

C program to print every 5 seconds and show total time when we exit

The program should print to the screen every 5 seconds and state "alive at %d milliseconds\n". When the user types in <Control><A> for the polling program or <Control><C> for the interrupt version, the program should stop and output:
program terminated by user. Total time is %d milliseconds %d seconds\n.
My Program:
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
volatile sig_atomic_t print_flag = false;
void handle_alarm( int sig ) {
print_flag = true;
}
int main() {
struct timeval start, stop;
double secs = 0;
char key_press;
char input_key;
int ascii_value;
float time_taken;
clock_t t;
t = clock();
gettimeofday(&start, NULL);
signal( SIGALRM, handle_alarm );
alarm( 5 );
for (;;) {
if ( print_flag ) {
print_flag = false;
alarm( 5 );
gettimeofday(&stop, NULL);
secs = (double)(stop.tv_usec - start.tv_usec) / 1000000 + (double)(stop.tv_sec - start.tv_sec) * 1000;
printf("Alive at %f ms \n",secs);
input_key=getchar();
ascii_value=input_key;
if(ascii_value==1) {
t = clock() - t;
time_taken = ((float)t)/CLOCKS_PER_SEC; // in seconds
printf("total time taken= %f sec", time_taken);
break;
}
}
}
}
I want the program to run continuously but when I press ctrl a it should terminate. The program prints "Alive at 5000.000 ms and stops printing. The program prints infinitely every 5 seconds if I don't add the code for terminating using ctrl A. How to make it work?
When you ask for input in this way, you are using synchronous blocking I/O. The process hangs until input is given. If you wish for your program to continue functioning while waiting for input you need to delve into asynchronous non-blocking I/O. Look up the select() function
https://en.wikipedia.org/wiki/Asynchronous_I/O
https://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html
After you do print_flag = false; in the for loop, you never set print_flag back to true again. Hence, the code in the if ( print_flag ) block is executed only once.
How to make it work?
To make it work, you need to set print_flag to true before you check whether it is true.

the use of getitimer and setitimer in C

I am writing the following C code to get the time taken to perform a simple operation using getitimer and setitimer.
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#define INTERVAL 1 /* number of milliseconds to go off */
int main() {
double sum = 0;
struct itimerval initial, updated;
initial.it_value.tv_sec = INTERVAL;
initial.it_value.tv_usec = 999999;
initial.it_interval = initial.it_value;
memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ));
printf("%ld\n", initial.it_value.tv_usec);
if (setitimer(ITIMER_VIRTUAL, &initial, NULL) == -1) {
perror("error calling setitimer()");
exit(1);
}
for (unsigned int i; i < 100; i++)
sum += 1./i;
if (getitimer(ITIMER_REAL, &updated) == -1) {
perror("error calling getitimer()");
exit(1);
}
printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
initial.it_value.tv_usec, updated.it_value.tv_usec,
initial.it_value.tv_usec - updated.it_value.tv_usec);
return 0;
}
I have compiled with:
$ gcc -o timer -std=c99 -Wall -pedantic getitimer.c -lrt -03
However, my answer is always 999999 (I have raised and decreased the 100):
./timer
999999
Time started = 999999
; Time endd = 0
: Time taken = 999999
What is my error? Also, I wanted to ask what is the highest precision I can get using a progrma like this?
Thanks very much!
the main thing I see is the division operations are using integer division. So:
initial.it_value.tv_sec = INTERVAL/1000000;
places 0 in tv.sec
initial.it_value.tv_usec = (INTERVAL/1000000) * 1000000;
places 0 in tv_usec
initial.it_interval = initial.it_value;
in general, when assigning a multi field struct, use memcpy() rather than a direct assignment. (direct assignment will work for initialization but not for assignment.)
So, the posted code sets the 'interval' to 0
so of course, the resulting values are 0
this is a key statement from the man page for setitimer() and getitimer()
"Timers decrement from it_value to zero, generate a signal, and reset to
it_interval. A timer which is set to zero (it_value is zero or the timer expires and it_interval is zero) stops."
Suggest: following edited
initial.it_value.tv_set = INTERVAL;
initial.it_value.tv_usec = 0;
memcpy( &(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ) );
...
the main problem with the latest code is that the call to getitimer() is referencing a different timer than the call to setitime()
However, the following code makes it simple to use
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
//#include <limits.h>
//#include <string.h>
// do not place comments on same line as #define statement
// always surround numeric values with parens to avoid 'text replacement' errors
// wrong comment: number of milliseconds to go off
// number of seconds in interval
#define INTERVAL (1)
// number of usec in interval
#define MICRO_INTERVAL (999999)
int main() {
//double sum = 0;
struct itimerval initial;
struct itimerval updated;
initial.it_value.tv_sec = INTERVAL;
initial.it_value.tv_usec = MICRO_INTERVAL;
initial.it_interval.tv_sec = INTERVAL;
initial.it_interval.tv_usec = MICRO_INTERVAL;
// remove this line: initial.it_interval = initial.it_value;
// remove this line: memcpy(&(initial.it_interval), &(initial.it_value), sizeof( initial.it_value ));
//printf("%ld\n", initial.it_value.tv_usec);
printf( "Time value: %ld.%ld\n", initial.it_value.tv_sec, initial.it_value.tv_usec );
printf( "Time interval: %ld.%ld\n", initial.it_interval.tv_sec, initial.it_interval.tv_usec );
if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
{
perror("error calling setitimer()");
exit(1);
}
//for (unsigned int i=0; i < 10; i++) // must initialize the 'i' variable
// sum += 1./i;
// the 'which' parameter should be 'ITIMER_VIRTUAL'
// as that is what was started in the call to setitimer()
//if (getitimer(ITIMER_REAL, &updated) == -1)
//{
// perror("error calling getitimer()");
// exit(1);
//}
if (setitimer(ITIMER_VIRTUAL, &initial, &updated) == -1)
{
perror("error calling setitimer()");
exit(1);
}
printf( "end interval counter: %ld.%ld\n", updated.it_interval.tv_sec, updated.it_interval.tv_usec );
printf( "end value counter: %ld.%ld\n", updated.it_value.tv_sec, updated.it_value.tv_usec );
//printf("Time started = %ld\n; Time ended = %ld\n: Time taken = %ld\n",
// initial.it_value.tv_usec, updated.it_value.tv_usec,
// initial.it_value.tv_usec - updated.it_value.tv_usec);
return 0;
}
// accuracy is +/-1 microsecond, not millisecond
The resulting output, even with nothing being done between the two calls to setitimer() is:
Time value: 1.999999
Time interval: 1.999999
end interval counter: 1.999999
end value counter: 2.3999
setitimer and getitimer are not the right functions to use for profiling. They relate to interval timers which are timers that generate an alarm (signal more accurately) when the timer expires.
The main options for achieving what you want are the clock or clock_gettime APIs.

Code not making using of more than one signal handler

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) ).

software Interrupt Service routine in C for windows operating system

#include <stdio.h>
#include <time.h>
#include <windows.h>
void Task()
{
printf("Hi");
}
int main ( ) {
time_t t;
clock_t start, end;
long i;
long count;
double x = 0.0;
count = 2;
start = clock();
time(&t);
printf(ctime(&t));
printf( "Counting to %ld\n", count );
if(count)
{
Task();
}
end = clock();
printf( "That took %f seconds and I counted up to %ld", (((double)(end-start)/CLOCKS_PER_SEC)), count );
printf( "\nThat also took %d clock tics\n ", clock());
return 0;
}
I want to get the start time and end time taken to execute the Task function. I am trying to create interrupt for the Task function but displaying Hi in the program. I am not successful with that. So could you please anyone can guide me regarding this.
Try starting with the Multimedia Timers. Another possible approach might be using CreateTimerQueueTimer() and friends.
There is no way of having interrupts in user-mode, only kernel-mode drivers can service interrupt requests.
However you can have a callback function called by the OS in a periodic way. On Windows you can achieve this using the multimedia times (however declared obsolete by Microsoft) or timer queue timers (check this, for example: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682485%28v=vs.85%29.aspx).
Here is an old test program I wrote that uses the Multimedia timers (obsolete but they still work on recent Windows versions...):
#include <stdio.h>
#include <windows.h>
volatile long timer = 0;
// Will be called every 1 ms
void CALLBACK timer_func(UINT uTimerID, UINT uMsg, DWORD *dwUser,
DWORD *dw1, DWORD *dw2)
{
timer++;
}
int main(int argc, char *argv[])
{
MMRESULT id = timeSetEvent(1, 0, (LPTIMECALLBACK) timer_func, NULL, TIME_PERIODIC);
printf("Waiting 10 seconds... ");
fflush(stdout);
Sleep(10000);
printf("ok. Timer = %ld.\n", timer);
timeKillEvent(id);
return 0;
}
If you just want to precisely measure how long a function call lasts, just use QueryPerformanceCounter() and QueryPerformanceFrequency():
#include <windows.h>
#include <stdio.h>
void task()
{
// do something...
}
int main()
{
LARGE_INTEGER start, stop, freq;
QueryPerformanceCounter(&start);
task();
QueryPerformanceCounter(&stop);
QueryPerformanceFrequency(&freq);
double time_len = (stop.QuadPart - start.QuadPart) / (double) freq.QuadPart;
printf("Task length: %0.8f seconds.\n", time_len);
}
New answer after discussion (see comments of my previous answer): you can implement an equivalent to the GetStopWatch() function you want this way:
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
// assuming we return times with microsecond resolution
#define STOPWATCH_TICKS_PER_US 1
uint64_t GetStopWatch()
{
LARGE_INTEGER t, freq;
uint64_t val;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&freq);
return (uint64_t) (t.QuadPart / (double) freq.QuadPart * 1000000);
}
void task()
{
// do something...
}
int main()
{
uint64_t start = GetStopWatch();
task();
uint64_t stop = GetStopWatch();
printf("Elapsed time (microseconds): %lld\n", stop - start);
}
Hope this helps.

Resources