Reputation: 5044
I'm building a multithreaded application with pthreads
and need a thread to periodically check some stuff. During the time in between this thread shouldn't use any CPU. Is this possible with usleep()
? Is usleep()
not busy waiting? Or is there a better solution?
Upvotes: 18
Views: 36997
Reputation: 78993
(usleep
is not part of the C standard, but of an ancient POSIX standard. But see below.)
No, the POSIX specification of usleep
clearly states
The usleep() function will cause the calling thread to be suspended from execution ...
so this clearly requires that it suspends execution and lets the resources to other processes or threads.
As already be mentioned by others, the POSIX function nanosleep
is now replacing usleep
and you should use that. C (since C11) has a function thrd_sleep
that is modeled after nanosleep
.
Upvotes: 14
Reputation: 82026
On Linux, it is implemented with the nanosleep system call which is not a busy wait.
Using strace, I can see that a call to usleep(1)
is translated into nanosleep({0, 1000}, NULL)
.
Upvotes: 6
Reputation: 182764
The function usleep
has been removed from SUSv4. You should probably use nanosleep
instead or timers (setitimer
, etc).
As R.. notes in the comments, should the sleep be implemented as a busy wait:
Thus:
Upvotes: 16
Reputation: 9442
Just be aware that both usleep() and nanosleep() can be interrupted by a signal. nanosleep() lets you pass in an extra timespec pointer where the remaining time will be stored if that happens. So if you really need to guarantee your delay times, you'll probably want to write a simple wrapper around nanosleep().
Beware that this is not tested, but something along these lines:
int myNanoSleep(time_t sec, long nanosec)
{
/* Setup timespec */
struct timespec req;
req.tv_sec = sec;
req.tv_nsec = nanosec;
/* Loop until we've slept long enough */
do
{
/* Store remainder back on top of the original required time */
if( 0 != nanosleep( &req, &req ) )
{
/* If any error other than a signal interrupt occurs, return an error */
if(errno != EINTR)
return -1;
}
else
{
/* nanosleep succeeded, so exit the loop */
break;
}
} while( req.tv_sec > 0 || req.tv_nsec > 0 )
return 0; /* Return success */
}
And if you ever need to wake the thread for something other than a periodic timeout, take a look at condition variables and pthread_cond_timedwait()
.
Upvotes: 10
Reputation: 57804
usleep()
is a C runtime library function built upon system timers.
nanosleep()
is a system call.
Only MS-DOS, and like ilk, implement the sleep functions as busy waits. Any actual operating system which offers multitasking can easily provide a sleep function as a simple extension of mechanisms for coordinating tasks and processes.
Upvotes: 1