implement time delay in c
I don't know exactly how to word a search for this.. so I haven't had any luck finding anything.. :S
I need to implement a time delay in C.
for example I want to do some stuff, then wait say 1 minute, then continue on doing stuff.
Did that make sense? Can anyone help me out?
Solution 1:
In standard C (C99), you can use time()
to do this, something like:
#include <time.h>
:
void waitFor (unsigned int secs) {
unsigned int retTime = time(0) + secs; // Get finishing time.
while (time(0) < retTime); // Loop until it arrives.
}
By the way, this assumes time()
returns a 1-second resolution value. I don't think that's mandated by the standard so you may have to adjust for it.
In order to clarify, this is the only way I'm aware of to do this with ISO C99 (and the question is tagged with nothing more than "C" which usually means portable solutions are desirable although, of course, vendor-specific solutions may still be given).
By all means, if you're on a platform that provides a more efficient way, use it. As several comments have indicated, there may be specific problems with a tight loop like this, with regard to CPU usage and battery life.
Any decent time-slicing OS would be able to drop the dynamic priority of a task that continuously uses its full time slice but the battery power may be more problematic.
However C specifies nothing about the OS details in a hosted environment, and this answer is for ISO C and ISO C alone (so no use of sleep
, select
, Win32 API calls or anything like that).
And keep in mind that POSIX sleep
can be interrupted by signals. If you are going to go down that path, you need to do something like:
int finishing = 0; // set finishing in signal handler
// if you want to really stop.
void sleepWrapper (unsigned int secs) {
unsigned int left = secs;
while ((left > 0) && (!finishing)) // Don't continue if signal has
left = sleep (left); // indicated exit needed.
}
Solution 2:
Here is how you can do it on most desktop systems:
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void wait( int seconds )
{ // Pretty crossplatform, both ALL POSIX compliant systems AND Windows
#ifdef _WIN32
Sleep( 1000 * seconds );
#else
sleep( seconds );
#endif
}
int
main( int argc, char **argv)
{
int running = 3;
while( running )
{ // do something
--running;
wait( 3 );
}
return 0; // OK
}
Here is how you can do it on a microcomputer / processor w/o timer:
int wait_loop0 = 10000;
int wait_loop1 = 6000;
// for microprocessor without timer, if it has a timer refer to vendor documentation and use it instead.
void
wait( int seconds )
{ // this function needs to be finetuned for the specific microprocessor
int i, j, k;
for(i = 0; i < seconds; i++)
{
for(j = 0; j < wait_loop0; j++)
{
for(k = 0; k < wait_loop1; k++)
{ // waste function, volatile makes sure it is not being optimized out by compiler
int volatile t = 120 * j * i + k;
t = t + 5;
}
}
}
}
int
main( int argc, char **argv)
{
int running = 3;
while( running )
{ // do something
--running;
wait( 3 );
}
return 0; // OK
}
The waitloop variables must be fine tuned, those did work pretty close for my computer, but the frequency scale thing makes it very imprecise for a modern desktop system; So don't use there unless you're bare to the metal and not doing such stuff.
Solution 3:
Check sleep(3) man page or MSDN for Sleep
Solution 4:
Although many implementations have the time
function return the current time in seconds, there is no guarantee that every implementation will do so (e.g. some may return milliseconds rather than seconds). As such, a more portable solution is to use the difftime
function.
difftime
is guaranteed by the C standard to return the difference in time in seconds between two time_t
values. As such we can write a portable time delay function which will run on all compliant implementations of the C standard.
#include <time.h>
void delay(double dly){
/* save start time */
const time_t start = time(NULL);
time_t current;
do{
/* get current time */
time(¤t);
/* break loop when the requested number of seconds have elapsed */
}while(difftime(current, start) < dly);
}
One caveat with the time
and difftime
functions is that the C standard never specifies a granularity. Most implementations have a granularity of one second. While this is all right for delays lasting several seconds, our delay function may wait too long for delays lasting under one second.
There is a portable standard C alternative: the clock
function.
The
clock
function returns the implementation’s best approximation to the processor time used by the program since the beginning of an implementation-defined era related only to the program invocation. To determine the time in seconds, the value returned by theclock
function should be divided by the value of the macroCLOCKS_PER_SEC
.
The clock
function solution is quite similar to our time
function solution:
#include <time.h>
void delay(double dly){
/* save start clock tick */
const clock_t start = clock();
clock_t current;
do{
/* get current clock tick */
current = clock();
/* break loop when the requested number of seconds have elapsed */
}while((double)(current-start)/CLOCKS_PER_SEC < dly);
}
There is a caveat in this case similar to that of time
and difftime
: the granularity of the clock
function is left to the implementation. For example, machines with 32-bit values for clock_t
with a resolution in microseconds may end up wrapping the value returned by clock
after 2147 seconds (about 36 minutes).
As such, consider using the time
and difftime
implementation of the delay function for delays lasting at least one second, and the clock
implementation for delays lasting under one second.
A final word of caution: clock
returns processor time rather than calendar time; clock
may not correspond with the actual elapsed time (e.g. if the process sleeps).
Solution 5:
For delays as large as one minute, sleep()
is a nice choice.
If someday, you want to pause on delays smaller than one second, you may want to consider poll()
with a timeout.
Both are POSIX.