Yes - older POSIX standards defined usleep()
, so this is available on Linux:
int usleep(useconds_t usec);
DESCRIPTION
The usleep() function suspends execution of the calling thread for
(at least) usec microseconds. The sleep may be lengthened slightly by
any system activity or by the time spent processing the call or by the
granularity of system timers.
usleep()
takes microseconds, so you will have to multiply the input by 1000 in order to sleep in milliseconds.
usleep()
has since been deprecated and subsequently removed from POSIX; for new code, nanosleep()
is preferred:
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);
DESCRIPTION
nanosleep()
suspends the execution of the calling thread until either at least the time specified in *req
has elapsed, or the
delivery of a signal that triggers the invocation of a handler in the
calling thread or that terminates the process.
The structure timespec is used to specify intervals of time with nanosecond precision. It is defined as follows:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
An example msleep()
function implemented using nanosleep()
, continuing the sleep if it is interrupted by a signal:
#include <time.h>
#include <errno.h>
/* msleep(): Sleep for the requested number of milliseconds. */
int msleep(long msec)
{
struct timespec ts;
int res;
if (msec < 0)
{
errno = EINVAL;
return -1;
}
ts.tv_sec = msec / 1000;
ts.tv_nsec = (msec % 1000) * 1000000;
do {
res = nanosleep(&ts, &ts);
} while (res && errno == EINTR);
return res;
}
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.
}
Best Answer
The kind of loop you describe is called a "busy wait". In real operating systems, sleeping does not cause a busy wait; it tells the operating system to not schedule the process in until the sleep period is over.